{
  "openapi": "3.0.0",
  "info": {
    "version": "3.0.0",
    "title": "Didit Verification API",
    "description": "API Verifikasi Identitas. Lakukan autentikasi dengan header x-api-key."
  },
  "servers": [
    {
      "url": "https://verification.didit.me"
    }
  ],
  "tags": [],
  "paths": {
    "/system/healthcheck": {
      "get": {
        "summary": "Pemeriksaan kesehatan layanan (publik, tanpa autentikasi)",
        "description": "Probe keaktifan publik tanpa autentikasi. Mengembalikan `HTTP 200` dengan `{status: \"ok\", timestamp}` saat layanan, DB, cache, dan broker dalam kondisi sehat.",
        "operationId": "get_system_healthcheck",
        "x-didit-sdk": {
          "resource": "system",
          "method": "healthcheck",
          "auth": "public",
          "server": false
        },
        "tags": [
          "System"
        ],
        "security": [
          {}
        ],
        "parameters": [],
        "responses": {
          "200": {
            "description": "Layanan sehat dan menerima permintaan. Isi respons selalu `{\"status\": \"ok\", \"timestamp\": \"<iso8601>\"}`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "status",
                    "timestamp"
                  ],
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "ok"
                      ],
                      "description": "Penanda liveness. Selalu berupa string literal `\"ok\"` pada respons 200.",
                      "example": "ok"
                    },
                    "timestamp": {
                      "type": "string",
                      "format": "date-time",
                      "description": "Waktu server saat pemeriksaan kesehatan dievaluasi, dalam format ISO 8601 dengan presisi milidetik dan akhiran `Z` (UTC).",
                      "example": "2026-04-21T16:42:50.445Z"
                    }
                  }
                },
                "examples": {
                  "Healthy": {
                    "summary": "Layanan aktif",
                    "value": {
                      "status": "ok",
                      "timestamp": "2026-04-21T16:42:50.445Z"
                    }
                  }
                }
              }
            }
          },
          "503": {
            "description": "Layanan tidak sehat — salah satu plugin pemeriksaan kesehatan yang dikonfigurasi (database, cache, broker) mengalami kegagalan. Isi respons sengaja dibuat minimal; status HTTP adalah sinyal utamanya. Coba lagi dengan penundaan eksponensial."
          },
          "5XX": {
            "description": "Layanan verifikasi mengalami gangguan atau tidak dapat dijangkau. Perlakukan setiap respons non-2xx sebagai \"tidak sehat\" dan coba lagi dengan backoff eksponensial."
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -i https://verification.didit.me/system/healthcheck"
          },
          {
            "lang": "Python",
            "label": "Python (requests)",
            "source": "import requests\n\nresp = requests.get(\"https://verification.didit.me/system/healthcheck\", timeout=5)\nresp.raise_for_status()\nprint(resp.json())  # {'status': 'ok', 'timestamp': '2026-04-21T16:42:50.445Z'}"
          },
          {
            "lang": "JavaScript",
            "label": "Node.js (fetch)",
            "source": "const res = await fetch(\"https://verification.didit.me/system/healthcheck\");\nif (!res.ok) throw new Error(`Didit unhealthy: ${res.status}`);\nconst body = await res.json();\nconsole.log(body); // { status: 'ok', timestamp: '2026-04-21T16:42:50.445Z' }"
          }
        ]
      }
    },
    "/v3/email/risk/": {
      "post": {
        "summary": "Memberi skor risiko pada alamat email",
        "description": "Mengembalikan sinyal keterkiriman, alamat sekali pakai, kebocoran data, pencocokan lintas sesi, dan intelijen risiko yang dinormalisasi tanpa mengirim OTP. Endpoint ini membuat sesi API dan mengembalikan id-nya sebagai `request_id`.\n\n**Keputusan.** `status` tingkat atas mencerminkan `email.status`. Status ini biasanya bernilai `Approved`; evaluasi risiko dapat menghasilkan `In Review` atau `Declined`.\n\n**Alias kompatibilitas.** Respons produksi menampilkan objek intelijen yang dinormalisasi sebagai `email.email_intelligence` dan `email.enrichment`. Nilainya identik. Integrasi baru dapat membaca `email.enrichment`. Kedua kunci tersebut tidak ada jika tidak ada data intelijen yang dapat digunakan yang dikembalikan.\n\n**Penagihan.** Panggilan produksi menggunakan harga Email Risk API. Permintaan dikenakan biaya begitu pencarian dimulai, bahkan saat beberapa kolom best-effort tidak tersedia.\n\n**Sandbox.** Kunci sandbox memvalidasi permintaan dan mengembalikan data deterministik yang disetujui tanpa mengirim email, menggunakan kredit, membuat sesi, atau berkontribusi ke Networks.\n\n**Autentikasi.** Kirim kunci API aplikasi Anda di `x-api-key`. Kredensial yang hilang atau tidak valid akan mengembalikan `403` - API ini tidak pernah mengembalikan `401`.\n\n**Batas laju.** Anggaran tulis bersama sebesar 300 permintaan per menit per kunci API di seluruh endpoint POST/PATCH/DELETE (pembuatan transaksi dan ingesti event memiliki anggaran terpisah sebesar 600).\n\n**Jejak sosial.** Atur `enable_social` ke `true` untuk menambahkan blok `email_social`: platform online tempat alamat ini terdaftar, dengan jumlah per kategori dan detail profil apa pun yang tersedia. `profiles_registered: 0` berarti platform telah diperiksa dan alamat tersebut tidak ditemukan di platform mana pun - sebuah jawaban valid yang dikenai biaya. Blok ini tidak ada jika add-on tidak diminta atau pemeriksaan tidak dapat diselesaikan, dan dalam kasus tersebut tidak dikenakan biaya. Penagihan menambahkan satu unit `email_social` per permintaan di luar harga endpoint ini sendiri.",
        "operationId": "post_v3email_risk",
        "x-didit-sdk": {
          "resource": "email",
          "method": "assess_risk",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Standalone APIs"
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST https://verification.didit.me/v3/email/risk/ \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"email\": \"alice@example.com\",\n    \"country_code\": \"US\",\n    \"vendor_data\": \"lead-123\",\n    \"metadata\": {\"source\": \"signup_prescreen\"}\n  }'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.email.assess_risk(\n    email=\"alice@example.com\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.email.assessRisk({\n  email: \"alice@example.com\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Email.AssessRisk(ctx, didit.EmailRiskRequest{\n\tEmail: \"alice@example.com\",\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.EmailRiskRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.email().assessRisk(EmailRiskRequest.builder()\n        .email(\"alice@example.com\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->email->assessRisk([\n    'email' => 'alice@example.com',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.email.assess_risk(email: \"alice@example.com\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Email.AssessRiskAsync(new EmailRiskRequest\n{\n    Email = \"alice@example.com\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EmailRiskRequest"
              },
              "examples": {
                "Minimal": {
                  "summary": "Beri skor alamat dengan pengaturan default",
                  "value": {
                    "email": "alice@example.com"
                  }
                },
                "Full context": {
                  "summary": "Beri skor dengan sinyal, petunjuk negara, dan ID korelasi",
                  "value": {
                    "email": "alice@example.com",
                    "country_code": "US",
                    "signals": {
                      "ip": "192.0.2.1",
                      "device_id": "8F0B8FDD-C2CB-4387-B20A-56E9B2E5A0D2",
                      "device_platform": "web",
                      "os_version": "14.4",
                      "app_version": "1.2.34",
                      "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.4 Safari/605.1.15"
                    },
                    "vendor_data": "lead-123",
                    "metadata": {
                      "source": "signup_prescreen"
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Evaluasi risiko selesai. Periksa `status` untuk melihat keputusannya; HTTP selalu `200` untuk pencarian yang selesai.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EmailRiskResponse"
                },
                "examples": {
                  "Clean address": {
                    "summary": "Alamat yang dapat dikirimi tanpa paparan kebocoran",
                    "value": {
                      "request_id": "82397be9-5921-4970-a979-2d5b43e08b33",
                      "status": "Approved",
                      "email": {
                        "status": "Approved",
                        "email": "alice@example.com",
                        "is_breached": false,
                        "breaches": [],
                        "is_disposable": false,
                        "is_undeliverable": false,
                        "verification_attempts": 0,
                        "verified_at": null,
                        "warnings": [],
                        "lifecycle": [],
                        "matches": [],
                        "email_intelligence": {
                          "score": 4.0,
                          "deliverable": "high",
                          "breach_risk_level": "Low",
                          "breach_risk_index": 4,
                          "is_recent_breach": false,
                          "is_frequent_breached": false,
                          "is_disposable": false,
                          "is_free_domain": false,
                          "is_breached": false,
                          "no_of_breaches": 0,
                          "reason_codes": []
                        },
                        "enrichment": {
                          "score": 4.0,
                          "deliverable": "high",
                          "breach_risk_level": "Low",
                          "breach_risk_index": 4,
                          "is_recent_breach": false,
                          "is_frequent_breached": false,
                          "is_disposable": false,
                          "is_free_domain": false,
                          "is_breached": false,
                          "no_of_breaches": 0,
                          "reason_codes": []
                        }
                      },
                      "vendor_data": "lead-123",
                      "metadata": {
                        "source": "signup_prescreen"
                      },
                      "created_at": "2026-09-01T10:30:00.123456+00:00"
                    }
                  },
                  "Breached address": {
                    "summary": "Alamat ditemukan dalam kebocoran data yang diketahui",
                    "value": {
                      "request_id": "d1e5c2a8-6f30-4c1a-8b2d-3e4f5a6b7c8d",
                      "status": "In Review",
                      "email": {
                        "status": "In Review",
                        "email": "bob@example.org",
                        "is_breached": true,
                        "breaches": [
                          {
                            "name": "ExampleBreach2023",
                            "domain": "example.org",
                            "breach_date": "2023-06-01",
                            "breach_emails_count": 1200000,
                            "description": "A data breach affecting example.org accounts.",
                            "logo_path": "https://logos.example.org/example.png",
                            "data_classes": [
                              "email_addresses",
                              "passwords"
                            ],
                            "is_verified": true
                          }
                        ],
                        "is_disposable": false,
                        "is_undeliverable": false,
                        "verification_attempts": 0,
                        "verified_at": null,
                        "warnings": [],
                        "lifecycle": [],
                        "matches": [],
                        "email_intelligence": {
                          "score": 58.0,
                          "deliverable": "high",
                          "breach_risk_level": "High",
                          "breach_risk_index": 72,
                          "is_recent_breach": true,
                          "is_frequent_breached": true,
                          "is_disposable": false,
                          "is_free_domain": true,
                          "is_breached": true,
                          "no_of_breaches": 4,
                          "reason_codes": [
                            {
                              "code": "IR-F784B630",
                              "direction": "risk",
                              "message": "Email's digital footprint diversity is Very Low",
                              "impact_level": "low"
                            }
                          ]
                        },
                        "enrichment": {
                          "score": 58.0,
                          "deliverable": "high",
                          "breach_risk_level": "High",
                          "breach_risk_index": 72,
                          "is_recent_breach": true,
                          "is_frequent_breached": true,
                          "is_disposable": false,
                          "is_free_domain": true,
                          "is_breached": true,
                          "no_of_breaches": 4,
                          "reason_codes": [
                            {
                              "code": "IR-F784B630",
                              "direction": "risk",
                              "message": "Email's digital footprint diversity is Very Low",
                              "impact_level": "low"
                            }
                          ]
                        }
                      },
                      "vendor_data": "lead-125",
                      "metadata": null,
                      "created_at": "2026-09-01T10:30:00.123456+00:00"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/EmailRiskValidationError"
          },
          "403": {
            "$ref": "#/components/responses/RiskPermissionDenied"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitedWrite"
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/ip/risk/": {
      "post": {
        "summary": "Memberi skor risiko pada alamat IP",
        "description": "Mengembalikan geolokasi, kepemilikan jaringan, penanda VPN/Tor dan pusat data, data ancaman, serta `country_mismatch` untuk alamat IP yang diberikan. Endpoint ini membuat sesi API dan mengembalikan id-nya sebagai `request_id`.\n\n**Keputusan.** `status` bernilai `In Review` jika negara yang teridentifikasi bertentangan dengan `claimed_country`, atau saat alamat dikaitkan dengan infrastruktur VPN, Tor, atau pusat data. Jika tidak, nilainya adalah `Approved`.\n\n**Upaya terbaik.** Pengayaan IP dilakukan dengan upaya terbaik. Jika tidak ada sumber pengayaan yang mengembalikan data yang dapat digunakan, endpoint mengembalikan respons disetujui dengan `ip.ip_address: null`, `ip.country_mismatch: null`, dan objek `ip.threat` kosong.\n\n**Penagihan.** Panggilan produksi menggunakan harga IP Risk API. Permintaan dikenakan biaya begitu pencarian dimulai.\n\n**Sandbox.** Kunci sandbox memvalidasi permintaan dan mengembalikan data deterministik berstatus disetujui tanpa menggunakan kredit, membuat sesi, atau berkontribusi ke Networks.\n\n**Autentikasi.** Kirim kunci API aplikasi Anda di `x-api-key`. Kredensial yang hilang atau tidak valid akan mengembalikan `403` - API ini tidak pernah mengembalikan `401`.\n\n**Batas laju.** Anggaran tulis bersama sebesar 300 permintaan per menit per kunci API di seluruh endpoint POST/PATCH/DELETE (pembuatan transaksi dan ingesti event memiliki anggaran terpisah sebesar 600).",
        "operationId": "post_v3ip_risk",
        "x-didit-sdk": {
          "resource": "ip",
          "method": "assess_risk",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Standalone APIs"
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST https://verification.didit.me/v3/ip/risk/ \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"ip_address\": \"8.8.8.8\",\n    \"claimed_country\": \"ESP\",\n    \"user_agent\": \"Mozilla/5.0\",\n    \"vendor_data\": \"lead-123\"\n  }'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.ip.assess_risk(\n    ip_address=\"8.8.8.8\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.ip.assessRisk({\n  ip_address: \"8.8.8.8\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.IP.AssessRisk(ctx, didit.IPRiskRequest{\n\tIPAddress: \"8.8.8.8\",\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.IPRiskRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.ip().assessRisk(IPRiskRequest.builder()\n        .ipAddress(\"8.8.8.8\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->ip->assessRisk([\n    'ip_address' => '8.8.8.8',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.ip.assess_risk(ip_address: \"8.8.8.8\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Ip.AssessRiskAsync(new IPRiskRequest\n{\n    IpAddress = \"8.8.8.8\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/IPRiskRequest"
              },
              "examples": {
                "Minimal": {
                  "summary": "Beri skor alamat dengan pengaturan default",
                  "value": {
                    "ip_address": "8.8.8.8"
                  }
                },
                "With claimed country": {
                  "summary": "Beri skor dengan negara yang diklaim untuk deteksi ketidakcocokan",
                  "value": {
                    "ip_address": "8.8.8.8",
                    "claimed_country": "ESP",
                    "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.4 Safari/605.1.15",
                    "vendor_data": "lead-123"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Evaluasi risiko selesai. Periksa `status` untuk melihat keputusannya; HTTP selalu `200` untuk pencarian yang selesai.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/IPRiskResponse"
                },
                "examples": {
                  "Clean residential IP": {
                    "summary": "Alamat tempat tinggal, negara yang diklaim cocok",
                    "value": {
                      "request_id": "9a96ed2a-721e-4b86-8cbf-d61eda529279",
                      "status": "Approved",
                      "ip": {
                        "status": "Approved",
                        "ip_address": "192.0.2.10",
                        "ip_country": "Spain",
                        "ip_country_code": "ES",
                        "ip_state": "Madrid",
                        "ip_city": "Madrid",
                        "latitude": 40.4168,
                        "longitude": -3.7038,
                        "isp": "Example Telecom",
                        "organization": "Example Telecom SA",
                        "is_vpn_or_tor": false,
                        "is_data_center": false,
                        "time_zone": "Europe/Madrid",
                        "time_zone_offset": "+0200",
                        "asn_number": 3352,
                        "asn_organization": "EXAMPLE-TELECOM",
                        "connection_type": "broadband",
                        "carrier": "Example Telecom",
                        "proxy_type": null,
                        "claimed_country": "ESP",
                        "country_mismatch": false,
                        "threat": {}
                      },
                      "vendor_data": "lead-123",
                      "metadata": null,
                      "created_at": "2026-09-01T10:30:00.123456+00:00"
                    }
                  },
                  "Datacenter mismatch": {
                    "summary": "Alamat pusat data bentrok dengan negara yang diklaim",
                    "value": {
                      "request_id": "5b1d4e9a-3c7b-4f8e-9a2d-1b0c9d8e7f6a",
                      "status": "In Review",
                      "ip": {
                        "status": "In Review",
                        "ip_address": "8.8.8.8",
                        "ip_country": "United States",
                        "ip_country_code": "US",
                        "ip_state": "California",
                        "ip_city": "Mountain View",
                        "latitude": 37.386,
                        "longitude": -122.0838,
                        "isp": "Google",
                        "organization": "Google LLC",
                        "is_vpn_or_tor": true,
                        "is_data_center": true,
                        "time_zone": "America/Los_Angeles",
                        "time_zone_offset": "-0700",
                        "asn_number": 15169,
                        "asn_organization": "GOOGLE, US",
                        "connection_type": "hosting",
                        "carrier": null,
                        "proxy_type": "VPN",
                        "claimed_country": "ESP",
                        "country_mismatch": true,
                        "threat": {
                          "is_proxy": true,
                          "is_data_center": true,
                          "is_tor": false
                        }
                      },
                      "vendor_data": "lead-126",
                      "metadata": null,
                      "created_at": "2026-09-01T10:30:00.123456+00:00"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/IPRiskValidationError"
          },
          "403": {
            "$ref": "#/components/responses/RiskPermissionDenied"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitedWrite"
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/phone/risk/": {
      "post": {
        "summary": "Memberi skor risiko pada nomor telepon",
        "description": "Selesaikan nomor telepon dan kembalikan sinyal operator, tipe saluran, porting, nomor sekali pakai, kecocokan lintas-sesi, serta intelijen risiko yang dinormalisasi tanpa mengirim OTP. Endpoint ini membuat sesi API dan mengembalikan ID-nya sebagai `request_id`.\n\n**Keputusan.** `status` tingkat atas mencerminkan `phone.status`. Nilainya biasanya `Approved`; evaluasi risiko dapat menghasilkan `In Review` atau `Declined`.\n\n**Alias kompatibilitas.** Respons produksi menampilkan objek intelijen yang dinormalisasi sebagai `phone.phone_intelligence` dan `phone.enrichment`. Nilainya identik. Integrasi baru dapat membaca `phone.enrichment`. Kedua kunci tersebut tidak ada jika data intelijen yang dapat digunakan tidak dikembalikan.\n\n**Penagihan.** Panggilan produksi menggunakan harga Phone Risk API. Permintaan ditagihkan setelah pencarian dimulai, bahkan jika beberapa kolom yang diupayakan sebaik mungkin tidak tersedia.\n\n**Sandbox.** Kunci sandbox memvalidasi permintaan dan mengembalikan data deterministik yang disetujui tanpa mengirim OTP, menggunakan kredit, membuat sesi, atau berkontribusi ke Networks.\n\n**Autentikasi.** Kirim kunci API aplikasi Anda di `x-api-key`. Kredensial yang tidak ada atau tidak valid akan mengembalikan `403` - API ini tidak pernah mengembalikan `401`.\n\n**Batas laju.** Anggaran tulis bersama sebesar 300 permintaan per menit per kunci API di seluruh endpoint POST/PATCH/DELETE (pembuatan transaksi dan penyerapan event memiliki anggaran terpisah sebesar 600).\n\n**Jejak sosial.** Atur `enable_social` ke `true` untuk menambahkan blok `phone_social`: platform daring tempat nomor ini terdaftar, beserta jumlah per kategori dan detail profil apa pun yang tersedia. `profiles_registered: 0` berarti platform telah diperiksa dan nomor tersebut tidak ditemukan di platform mana pun - jawaban yang valid dan dapat ditagih. Blok ini tidak ada jika fitur tambahan tidak diminta atau pemeriksaan tidak dapat diselesaikan, dan tidak ditagih dalam kasus tersebut. Penagihan menambahkan satu unit `phone_social` per permintaan di atas harga endpoint ini sendiri.",
        "operationId": "post_v3phone_risk",
        "x-didit-sdk": {
          "resource": "phone",
          "method": "assess_risk",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Standalone APIs"
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST https://verification.didit.me/v3/phone/risk/ \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"phone_number\": \"+14155552671\",\n    \"country_code\": \"US\",\n    \"vendor_data\": \"lead-123\",\n    \"metadata\": {\"source\": \"signup_prescreen\"}\n  }'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.phone.assess_risk(\n    phone_number=\"+14155552671\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.phone.assessRisk({\n  phone_number: \"+14155552671\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Phone.AssessRisk(ctx, didit.PhoneRiskRequest{\n\tPhoneNumber: \"+14155552671\",\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.PhoneRiskRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.phone().assessRisk(PhoneRiskRequest.builder()\n        .phoneNumber(\"+14155552671\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->phone->assessRisk([\n    'phone_number' => '+14155552671',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.phone.assess_risk(phone_number: \"+14155552671\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Phone.AssessRiskAsync(new PhoneRiskRequest\n{\n    PhoneNumber = \"+14155552671\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PhoneRiskRequest"
              },
              "examples": {
                "Minimal": {
                  "summary": "Beri skor nomor dengan pengaturan default",
                  "value": {
                    "phone_number": "+14155552671"
                  }
                },
                "Full context": {
                  "summary": "Beri skor dengan sinyal, petunjuk negara, dan ID korelasi",
                  "value": {
                    "phone_number": "+14155552671",
                    "country_code": "US",
                    "signals": {
                      "ip": "192.0.2.1",
                      "device_id": "8F0B8FDD-C2CB-4387-B20A-56E9B2E5A0D2",
                      "device_platform": "ios",
                      "device_model": "iPhone17,2",
                      "os_version": "18.0.1",
                      "app_version": "1.2.34",
                      "user_agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 18_0_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.0 Mobile/15E148 Safari/604.1"
                    },
                    "vendor_data": "lead-123",
                    "metadata": {
                      "source": "signup_prescreen"
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Evaluasi risiko selesai. Periksa `status` untuk melihat keputusannya; HTTP selalu `200` untuk pencarian yang selesai.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PhoneRiskResponse"
                },
                "examples": {
                  "Clean mobile number": {
                    "summary": "Nomor ponsel bersih dengan cakupan intelijen",
                    "value": {
                      "request_id": "4fd09d2e-9bc9-4c4e-9c46-7f625ac0ab62",
                      "status": "Approved",
                      "phone": {
                        "status": "Approved",
                        "phone_number_prefix": "+1",
                        "phone_number": "4155552671",
                        "full_number": "+14155552671",
                        "country_code": "US",
                        "country_name": "United States",
                        "carrier": {
                          "name": "Example Mobile",
                          "type": "mobile"
                        },
                        "is_disposable": false,
                        "is_virtual": false,
                        "verification_method": null,
                        "verification_attempts": 0,
                        "verified_at": null,
                        "warnings": [],
                        "lifecycle": [],
                        "matches": [],
                        "phone_intelligence": {
                          "score": 3.0,
                          "phone_type_risk": "Low",
                          "phone_trust_index": 97,
                          "network_stability_index": 95,
                          "is_disposable": false,
                          "is_ported": false,
                          "is_recently_ported": false,
                          "carrier_type": "mobile",
                          "reason_codes": []
                        },
                        "enrichment": {
                          "score": 3.0,
                          "phone_type_risk": "Low",
                          "phone_trust_index": 97,
                          "network_stability_index": 95,
                          "is_disposable": false,
                          "is_ported": false,
                          "is_recently_ported": false,
                          "carrier_type": "mobile",
                          "reason_codes": []
                        }
                      },
                      "vendor_data": "lead-123",
                      "metadata": {
                        "source": "signup_prescreen"
                      },
                      "created_at": "2026-09-01T10:30:00.123456+00:00"
                    }
                  },
                  "Number in review": {
                    "summary": "Nomor sekali pakai atau virtual ditandai untuk ditinjau",
                    "value": {
                      "request_id": "8c22e1f0-4b3d-4a3a-9d1e-2f6b7c8d9e0f",
                      "status": "In Review",
                      "phone": {
                        "status": "In Review",
                        "phone_number_prefix": "+44",
                        "phone_number": "7700900123",
                        "full_number": "+447700900123",
                        "country_code": "GB",
                        "country_name": "United Kingdom",
                        "carrier": {
                          "name": "Example VoIP",
                          "type": "voip"
                        },
                        "is_disposable": true,
                        "is_virtual": true,
                        "verification_method": null,
                        "verification_attempts": 0,
                        "verified_at": null,
                        "warnings": [],
                        "lifecycle": [],
                        "matches": [],
                        "phone_intelligence": {
                          "score": 72.0,
                          "phone_type_risk": "High",
                          "phone_trust_index": 28,
                          "network_stability_index": 40,
                          "is_disposable": true,
                          "is_ported": true,
                          "is_recently_ported": true,
                          "carrier_type": "voip",
                          "reason_codes": [
                            {
                              "code": "IR-5AC67A32",
                              "direction": "risk",
                              "message": "Phone type identified as non-mobile",
                              "impact_level": "medium"
                            }
                          ]
                        },
                        "enrichment": {
                          "score": 72.0,
                          "phone_type_risk": "High",
                          "phone_trust_index": 28,
                          "network_stability_index": 40,
                          "is_disposable": true,
                          "is_ported": true,
                          "is_recently_ported": true,
                          "carrier_type": "voip",
                          "reason_codes": [
                            {
                              "code": "IR-5AC67A32",
                              "direction": "risk",
                              "message": "Phone type identified as non-mobile",
                              "impact_level": "medium"
                            }
                          ]
                        }
                      },
                      "vendor_data": "lead-124",
                      "metadata": null,
                      "created_at": "2026-09-01T10:30:00.123456+00:00"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/PhoneRiskValidationError"
          },
          "403": {
            "$ref": "#/components/responses/RiskPermissionDenied"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitedWrite"
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/session/": {
      "post": {
        "summary": "Buat sesi verifikasi",
        "description": "Buat sesi Verifikasi Pengguna (KYC) atau Verifikasi Bisnis (KYB) dan terima `url` verifikasi yang di-hosting beserta `session_token` untuk dialihkan atau disematkan bagi pengguna akhir Anda. `workflow_id` memilih langkah verifikasi mana yang dijalankan dan apakah sesi tersebut merupakan KYC atau KYB.\n\nPanggil ini dari backend Anda (jangan pernah dari browser — kunci API bersifat rahasia) kapan pun pengguna atau bisnis perlu diverifikasi: saat pendaftaran, sebelum tindakan sensitif, atau ketika verifikasi ulang diperlukan. Prasyarat: alur kerja yang dipublikasikan (dibuat di halaman [Workflows](https://docs.didit.me/id/console/workflows) Console) dan kunci API aplikasi dengan kredit yang tersedia. Aplikasi sandbox melewati pemeriksaan kredit.\n\n**Idempotensi:** ketika `vendor_data` diberikan dan sesi yang belum selesai (`Not Started`, `In Progress`, `Resubmitted`, atau `Awaiting User`) dengan `vendor_data` yang sama sudah ada pada **versi publikasi terbaru saat ini** dari alur kerja tersebut (dan sesi tersebut sudah memiliki URL verifikasi yang di-hosting), sesi yang sudah ada akan dikembalikan (tetap `201`) alih-alih membuat duplikat — dengan `callback` dan `metadata` diperbarui ke nilai baru yang diberikan. Sesi yang belum selesai yang dibuat pada versi alur kerja yang lebih lama (versi yang telah dipublikasikan ulang sejak saat itu) **tidak** digunakan kembali; sesi baru yang disematkan ke versi publikasi terbaru akan dibuat sebagai gantinya. Sesi dalam `Approved`, `Declined`, `In Review`, `Expired`, `Abandoned`, atau `Kyc Expired` tidak pernah digunakan kembali.\n\n**Efek samping:** URL verifikasi yang di-hosting dibuat dan disimpan; jika `contact_details.send_notification_emails` bernilai `true` dan email diberikan, email undangan verifikasi akan dikirimkan. Sesi kedaluwarsa setelah waktu kedaluwarsa sesi yang dikonfigurasi pada alur kerja. Untuk alur kerja KYB, `contact_details.phone` dan `expected_details` diabaikan.",
        "operationId": "post_v3_session_create",
        "x-didit-sdk": {
          "resource": "sessions",
          "method": "create",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Sessions"
        ],
        "responses": {
          "201": {
            "description": "Sesi dibuat (atau dikembalikan, jika sesi yang belum selesai dengan `vendor_data` yang sama sudah ada pada versi alur kerja terbaru yang dipublikasikan). Responsnya adalah sesi yang diserialisasi, termasuk `url` verifikasi yang di-hosting untuk mengarahkan pengguna.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "session_id",
                    "session_number",
                    "session_token",
                    "url",
                    "vendor_data",
                    "metadata",
                    "status",
                    "workflow_id",
                    "workflow_version",
                    "callback"
                  ],
                  "properties": {
                    "session_id": {
                      "type": "string",
                      "format": "uuid",
                      "description": "Pengenal unik sesi verifikasi. Gunakan id ini saat memanggil `GET /v3/session/{sessionId}/decision/`.",
                      "example": "11111111-2222-3333-4444-555555555555"
                    },
                    "session_number": {
                      "type": "integer",
                      "description": "Nomor urut yang mudah dibaca manusia dan ditetapkan ke sesi di dalam aplikasi Anda. Berguna untuk dukungan dan dasbor.",
                      "example": 43762
                    },
                    "session_token": {
                      "type": "string",
                      "description": "Token 12 karakter yang aman untuk URL yang mengizinkan pengguna akhir untuk mengakses alur verifikasi yang di-hosting di `url`. Berlaku sampai sesi kedaluwarsa. Perlakukan sebagai rahasia — siapa pun yang memilikinya dapat membuka alur verifikasi untuk sesi ini.",
                      "example": "3FaJ9wLqX2Mz"
                    },
                    "url": {
                      "type": "string",
                      "format": "uri",
                      "description": "URL verifikasi yang di-hosting untuk mengarahkan pengguna akhir. URL ini menyematkan `session_token` dan, jika dikonfigurasi, menggunakan domain White Label Anda. Jika permintaan menyertakan `language`, URL tersebut berisi segmen jalur bahasa - `https://verify.didit.me/{language}/session/{session_token}` (misalnya `/es/session/...`); tanpa `language`, segmen tersebut dihilangkan.",
                      "example": "https://verify.didit.me/session/3FaJ9wLqX2Mz"
                    },
                    "vendor_data": {
                      "type": "string",
                      "nullable": true,
                      "description": "Pengenal yang Anda teruskan dalam permintaan untuk menautkan sesi ke pengguna atau bisnis di sistem Anda sendiri. Dikembalikan secara persis sama. Bernilai null jika tidak diberikan.",
                      "example": "user-123"
                    },
                    "metadata": {
                      "description": "Payload JSON arbitrer yang Anda simpan bersama sesi pada saat pembuatan. Dikembalikan persis apa adanya — nilai JSON apa pun yang Anda kirim (objek, string, angka, array) dikembalikan sebagaimana mestinya, meskipun objek JSON disarankan. Tidak ditampilkan kepada pengguna akhir. Selalu ada dalam respons; `null` jika tidak diberikan pada saat pembuatan.",
                      "example": {
                        "user_type": "premium",
                        "account_id": "ABC123"
                      }
                    },
                    "tags": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Tag pada sesi, berdasarkan nama.",
                      "example": [
                        "VIP",
                        "ONBOARDING Q4"
                      ]
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "Not Started",
                        "In Progress",
                        "Approved",
                        "Declined",
                        "In Review",
                        "Expired",
                        "Abandoned",
                        "Kyc Expired",
                        "Resubmitted",
                        "Awaiting User"
                      ],
                      "description": "Status sesi saat ini. Sesi yang baru dibuat mengembalikan `Not Started`. Jika sesi yang belum selesai sudah ada untuk `vendor_data` yang sama pada versi publikasi terbaru dari alur kerja, status yang dikembalikan mencerminkan sesi yang sudah ada tersebut.",
                      "example": "Not Started"
                    },
                    "callback": {
                      "type": "string",
                      "format": "uri",
                      "nullable": true,
                      "description": "URL pengalihan akhir tempat pengguna diarahkan setelah menyelesaikan alur. Didit menambahkan `?verificationSessionId={session_id}&status={status}` ke URL ini. Kembali ke URL callback alur kerja yang dikonfigurasi jika tidak diberikan dalam permintaan; `null` jika keduanya tidak diatur. Jika aplikasi memiliki domain yang diizinkan dan URL ini adalah URL web di luar domain tersebut (misalnya default alur kerja yang diatur sebelum daftar diubah), alur yang di-hosting tidak mengalihkan pengguna ke URL tersebut.",
                      "example": "https://example.com/verification/callback"
                    },
                    "workflow_id": {
                      "type": "string",
                      "format": "uuid",
                      "description": "Pengidentifikasi stabil dari alur kerja tempat sesi ini berjalan. Selalu merupakan pengidentifikasi grup stabil dari alur kerja — meskipun Anda mereferensikan UUID versi alur kerja tertentu dalam permintaan (pencarian yang kompatibel dengan versi sebelumnya), respons tetap membawa `workflow_id` yang stabil. Gunakan ini untuk mengorelasikan sesi dengan alur kerja yang Anda konfigurasikan di Konsol.",
                      "example": "11111111-2222-3333-4444-555555555555"
                    },
                    "workflow_version": {
                      "type": "integer",
                      "description": "Nomor versi dari versi alur kerja yang dipublikasikan tempat sesi disematkan saat pembuatan. Didit menentukan versi alur kerja terbaru yang dipublikasikan untuk `workflow_id` saat sesi dibuat, dan sesi tetap menjalankan versi tersebut bahkan jika alur kerja dipublikasikan ulang nanti.",
                      "example": 3
                    }
                  }
                },
                "examples": {
                  "KYC session": {
                    "summary": "Sesi KYC dibuat",
                    "value": {
                      "session_id": "11111111-2222-3333-4444-555555555555",
                      "session_number": 43762,
                      "session_token": "3FaJ9wLqX2Mz",
                      "url": "https://verify.didit.me/en/session/3FaJ9wLqX2Mz",
                      "vendor_data": "user-123",
                      "metadata": {
                        "user_type": "premium",
                        "account_id": "ABC123"
                      },
                      "status": "Not Started",
                      "workflow_id": "11111111-2222-3333-4444-555555555555",
                      "workflow_version": 3,
                      "callback": "https://example.com/verification/callback"
                    }
                  },
                  "KYB session": {
                    "summary": "Sesi KYB dibuat",
                    "value": {
                      "session_id": "22222222-3333-4444-5555-666666666666",
                      "session_number": 43763,
                      "session_token": "Yk7pQ2vN8aBc",
                      "url": "https://verify.didit.me/en/session/Yk7pQ2vN8aBc",
                      "vendor_data": "company-acme-001",
                      "metadata": {
                        "tier": "enterprise"
                      },
                      "status": "Not Started",
                      "workflow_id": "33333333-4444-5555-6666-777777777777",
                      "workflow_version": 1,
                      "callback": "https://example.com/kyb/callback"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Permintaan tidak valid — payload gagal validasi (`workflow_id` tidak ada atau tidak dikenal, `language` tidak valid, `vendor_data` masuk daftar blokir, `portrait_image` salah bentuk, `address` tanpa `country`/`poa_country`, `sandbox_scenario` tidak valid, dokumen, kolom, atau nilai `sign` ditolak oleh langkah Tanda Tangan Elektronik alur kerja, seperti `signature_document_not_supported`, `signature_document_conversion_failed`, `field_anchor_not_found`, atau `field_value_missing`, dll.) atau organisasi Anda tidak memiliki cukup kredit untuk memulai sesi.\n\nIsi respons berupa objek dengan kunci nama kolom yang bermasalah (atau `detail` untuk kesalahan di luar kolom). Nilai berupa **larik string** untuk kegagalan validasi input (misalnya kolom wajib yang hilang, bahasa tidak valid, gambar potret melebihi batas ukuran) dan **string biasa** untuk kegagalan yang terdeteksi saat membuat sesi (`workflow_id` tidak dikenal, `vendor_data` masuk daftar blokir, tidak ada wajah referensi yang tersedia untuk alur kerja Pencocokan Wajah). Tangani kedua bentuk respons tersebut.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "Pesan kesalahan yang mudah dibaca manusia untuk kesalahan non-kolom (mis. kredit tidak mencukupi). Kegagalan tingkat kolom menggunakan nama kolom sebagai kunci, dengan nilai string atau array yang berisi string.",
                      "example": "You don't have enough credits to perform this request. Please top up at https://business.didit.me"
                    }
                  }
                },
                "examples": {
                  "Missing workflow_id": {
                    "summary": "Kolom wajib tidak disertakan (bentuk array string)",
                    "value": {
                      "workflow_id": [
                        "This field is required."
                      ]
                    }
                  },
                  "Invalid workflow_id": {
                    "summary": "workflow_id tidak dikenal (bentuk string biasa)",
                    "value": {
                      "workflow_id": "Invalid workflow_id."
                    }
                  },
                  "Insufficient credits": {
                    "summary": "Organisasi kehabisan kredit",
                    "value": {
                      "detail": "You don't have enough credits to perform this request. Please top up at https://business.didit.me"
                    }
                  },
                  "Blocklisted vendor_data": {
                    "summary": "vendor_data masuk dalam daftar blokir",
                    "value": {
                      "vendor_data": "This user or business has been blocked and cannot create new verification sessions."
                    }
                  },
                  "Portrait image too large": {
                    "summary": "portrait_image gagal dalam validasi ukuran",
                    "value": {
                      "portrait_image": [
                        "Image size exceeds 2MB."
                      ]
                    }
                  },
                  "No stored face for vendor_data": {
                    "summary": "Alur kerja Pencocokan Wajah tanpa portrait_image dan tanpa wajah tersimpan untuk pengguna vendor_data",
                    "value": {
                      "portrait_image": "No stored face image was found for this user. Send a portrait_image, or complete an approved verification with face liveness or an ID document for this vendor_data first."
                    }
                  },
                  "Portrait image required without vendor_data": {
                    "summary": "Alur kerja Pencocokan Wajah tanpa portrait_image dan tanpa vendor_data",
                    "value": {
                      "portrait_image": "A portrait image is required to perform face match for this workflow. Send a portrait_image, or provide the vendor_data of a user with a previously stored face image to reuse it."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Autentikasi atau otorisasi gagal. Kunci yang salah, dicabut, atau kedaluwarsa mengembalikan `401`. Endpoint mengembalikan `403` jika header `x-api-key` tidak ada atau kunci API valid tetapi klien tidak memiliki izin untuk membuat sesi di aplikasi ini (misalnya kunci API milik organisasi yang berbeda). Kegagalan ini memiliki body respons yang sama: `{\"detail\": \"You do not have permission to perform this action.\"}`. Periksa apakah header `x-api-key` ada dan milik aplikasi yang dimaksud, ambil kembali kunci API aplikasi melalui [Auth API](/id/auth-api/get-credentials) jika diperlukan, lalu coba lagi.\n\n**Aplikasi yang dihapus:** selama beberapa menit setelah aplikasi dihapus, permintaan yang dibuat dengan salah satu kunci API-nya dapat mengembalikan `{\"detail\": \"This application was deleted.\", \"code\": \"application_deleted\"}`. Jangan coba lagi: aplikasi dan kunci API-nya sudah tidak ada. Setelah beberapa menit tersebut, kunci akan ditolak seperti kunci tidak valid lainnya.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "example": "You do not have permission to perform this action."
                    },
                    "code": {
                      "type": "string",
                      "description": "Alasan yang dapat dibaca mesin, hanya ada pada beberapa kegagalan. `application_deleted`: kunci API milik aplikasi yang telah dihapus.",
                      "example": "application_deleted"
                    }
                  },
                  "required": [
                    "detail"
                  ]
                },
                "examples": {
                  "Missing or invalid API key": {
                    "summary": "Tidak ada header `x-api-key` atau kunci API tidak valid",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "No permission": {
                    "summary": "Klien tidak dapat membuat sesi",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Application deleted": {
                    "summary": "Kunci API dari aplikasi yang dihapus",
                    "value": {
                      "detail": "This application was deleted.",
                      "code": "application_deleted"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Batas laju terlampaui — lebih dari 600 permintaan pembuatan sesi dalam jendela 60 detik dari kunci API / IP yang sama. Periksa `Retry-After` dan lakukan backoff sebelum mencoba lagi.\n\n**Catatan:** Kode sumber juga mendefinisikan `FREE_SESSION_RATE_LIMIT` sebesar 10 panggilan/menit bersama dengan `PAID_SESSION_RATE_LIMIT=600` (`sessions/serializers/session.py`), tetapi batas atas paket gratis tersebut **tidak diterapkan pada endpoint V3 ini** — middleware batas laju memberlakukan `SESSION_CREATE_RATE_LIMIT` 600/menit apa pun paketnya. 600/menit adalah satu-satunya batasan yang dapat Anda capai di sini.",
            "headers": {
              "Retry-After": {
                "description": "Detik yang harus ditunggu pemanggil sebelum mencoba lagi mengirimkan permintaan.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "example": 42
                }
              },
              "X-RateLimit-Limit": {
                "description": "Jumlah permintaan maksimum yang diizinkan dalam jendela 60 detik saat ini untuk batas yang terlampaui (600 untuk pembuatan sesi). Tidak ada pada varian kuota sandbox.",
                "schema": {
                  "type": "integer",
                  "example": 600
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Jumlah permintaan yang masih diizinkan pada jendela saat ini untuk batas yang dilanggar. Tidak ada pada varian kuota sandbox.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "example": 0
                }
              },
              "X-RateLimit-Reset": {
                "description": "Detik epoch UTC saat jendela batas laju saat ini disetel ulang. Tidak ada pada varian kuota sandbox.",
                "schema": {
                  "type": "integer",
                  "minimum": 0,
                  "example": 1747497600
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "Penjelasan pelanggaran batas laju yang mudah dibaca manusia. Gunakan pesan ini untuk membedakan batas mana dari ketiga batas yang terlampaui.",
                      "example": "Session creation rate limit exceeded. You can make up to 600 requests per minute."
                    }
                  }
                },
                "examples": {
                  "Session-create limit": {
                    "summary": "Lebih dari 600 permintaan pembuatan sesi per menit",
                    "value": {
                      "detail": "Session creation rate limit exceeded. You can make up to 600 requests per minute."
                    }
                  },
                  "Sandbox session quota": {
                    "summary": "Aplikasi sandbox melebihi 500 sesi dalam 24 jam",
                    "value": {
                      "detail": "Sandbox session quota exceeded (500 sessions per 24h). Wait for the window to reset. Expected available in 3600 seconds."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL",
            "source": "curl -X POST 'https://verification.didit.me/v3/session/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"workflow_id\": \"11111111-2222-3333-4444-555555555555\",\n    \"vendor_data\": \"user-123\",\n    \"callback\": \"https://example.com/verification/callback\",\n    \"callback_method\": \"both\",\n    \"metadata\": {\"user_type\": \"premium\", \"account_id\": \"ABC123\"},\n    \"language\": \"en\",\n    \"contact_details\": {\n      \"email\": \"john.doe@example.com\",\n      \"send_notification_emails\": true,\n      \"email_lang\": \"en\",\n      \"phone\": \"+14155552671\"\n    },\n    \"expected_details\": {\n      \"first_name\": \"John\",\n      \"last_name\": \"Doe\",\n      \"date_of_birth\": \"1990-05-15\",\n      \"id_country\": \"USA\",\n      \"expected_document_types\": [\"P\", \"ID\"]\n    }\n  }'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.create(\n    workflow_id=\"11111111-2222-3333-4444-555555555555\",\n    vendor_data=\"user-123\",\n    callback=\"https://example.com/verification/callback\",\n    callback_method=\"both\",\n    metadata={\"user_type\": \"premium\", \"account_id\": \"ABC123\"},\n    language=\"en\",\n    contact_details={\n        \"email\": \"john.doe@example.com\",\n        \"send_notification_emails\": True,\n        \"email_lang\": \"en\",\n        \"phone\": \"+14155552671\",\n    },\n    expected_details={\n        \"first_name\": \"John\",\n        \"last_name\": \"Doe\",\n        \"date_of_birth\": \"1990-05-15\",\n        \"nationality\": \"USA\",\n        \"id_country\": \"USA\",\n        \"expected_document_types\": [\"P\", \"ID\"],\n    },\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.create({\n  workflow_id: \"11111111-2222-3333-4444-555555555555\",\n  vendor_data: \"user-123\",\n  callback: \"https://example.com/verification/callback\",\n  callback_method: \"both\",\n  metadata: { user_type: \"premium\", account_id: \"ABC123\" },\n  language: \"en\",\n  contact_details: {\n    email: \"john.doe@example.com\",\n    send_notification_emails: true,\n    email_lang: \"en\",\n    phone: \"+14155552671\",\n  },\n  expected_details: {\n    first_name: \"John\",\n    last_name: \"Doe\",\n    date_of_birth: \"1990-05-15\",\n    nationality: \"USA\",\n    id_country: \"USA\",\n    expected_document_types: [\"P\", \"ID\"],\n  },\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.Create(ctx, didit.SessionsCreateParams{\n\tWorkflowID:     \"11111111-2222-3333-4444-555555555555\",\n\tVendorData:     didit.String(\"user-123\"),\n\tCallback:       didit.String(\"https://example.com/verification/callback\"),\n\tCallbackMethod: didit.Some(didit.SessionsCreateParamsCallbackMethod(\"both\")),\n\tMetadata:       didit.Some[any](map[string]any{\"user_type\": \"premium\", \"account_id\": \"ABC123\"}),\n\tLanguage:       didit.Some(didit.SessionsCreateParamsLanguage(\"en\")),\n\tContactDetails: didit.Some(didit.SessionsCreateParamsContactDetails{\n\t\tEmail:                  didit.String(\"john.doe@example.com\"),\n\t\tSendNotificationEmails: didit.Bool(true),\n\t\tEmailLang:              didit.Some(didit.SessionsCreateParamsContactDetailsEmailLang(\"en\")),\n\t\tPhone:                  didit.String(\"+14155552671\"),\n\t}),\n\tExpectedDetails: didit.Some(didit.SessionsCreateParamsExpectedDetails{\n\t\tFirstName:             didit.String(\"John\"),\n\t\tLastName:              didit.String(\"Doe\"),\n\t\tDateOfBirth:           didit.String(\"1990-05-15\"),\n\t\tNationality:           didit.String(\"USA\"),\n\t\tIDCountry:             didit.String(\"USA\"),\n\t\tExpectedDocumentTypes: didit.Some([]didit.SessionsCreateParamsExpectedDetailsExpectedDocumentTypes{\"P\", \"ID\"}),\n\t}),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.time.LocalDate;\nimport java.util.List;\nimport java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.SessionsCreateParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().create(SessionsCreateParams.builder()\n        .workflowId(\"11111111-2222-3333-4444-555555555555\")\n        .vendorData(\"user-123\")\n        .callback(\"https://example.com/verification/callback\")\n        .callbackMethod(SessionsCreateParams.CallbackMethod.of(\"both\"))\n        .metadata(Map.of(\"user_type\", \"premium\", \"account_id\", \"ABC123\"))\n        .language(SessionsCreateParams.Language.of(\"en\"))\n        .contactDetails(SessionsCreateParams.ContactDetails.builder()\n                .email(\"john.doe@example.com\")\n                .sendNotificationEmails(true)\n                .emailLang(SessionsCreateParams.ContactDetails.EmailLang.of(\"en\"))\n                .phone(\"+14155552671\")\n                .build())\n        .expectedDetails(SessionsCreateParams.ExpectedDetails.builder()\n                .firstName(\"John\")\n                .lastName(\"Doe\")\n                .dateOfBirth(LocalDate.parse(\"1990-05-15\"))\n                .nationality(\"USA\")\n                .idCountry(\"USA\")\n                .expectedDocumentTypes(List.of(SessionsCreateParams.ExpectedDetails.ExpectedDocumentTypes.of(\"P\"), SessionsCreateParams.ExpectedDetails.ExpectedDocumentTypes.of(\"ID\")))\n                .build())\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->sessions->create([\n    'workflow_id' => '11111111-2222-3333-4444-555555555555',\n    'vendor_data' => 'user-123',\n    'callback' => 'https://example.com/verification/callback',\n    'callback_method' => 'both',\n    'metadata' => ['user_type' => 'premium', 'account_id' => 'ABC123'],\n    'language' => 'en',\n    'contact_details' => [\n        'email' => 'john.doe@example.com',\n        'send_notification_emails' => true,\n        'email_lang' => 'en',\n        'phone' => '+14155552671',\n    ],\n    'expected_details' => [\n        'first_name' => 'John',\n        'last_name' => 'Doe',\n        'date_of_birth' => '1990-05-15',\n        'nationality' => 'USA',\n        'id_country' => 'USA',\n        'expected_document_types' => ['P', 'ID'],\n    ],\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.create(\n  workflow_id: \"11111111-2222-3333-4444-555555555555\",\n  vendor_data: \"user-123\",\n  callback: \"https://example.com/verification/callback\",\n  callback_method: \"both\",\n  metadata: { user_type: \"premium\", account_id: \"ABC123\" },\n  language: \"en\",\n  contact_details: {\n    email: \"john.doe@example.com\",\n    send_notification_emails: true,\n    email_lang: \"en\",\n    phone: \"+14155552671\",\n  },\n  expected_details: {\n    first_name: \"John\",\n    last_name: \"Doe\",\n    date_of_birth: \"1990-05-15\",\n    nationality: \"USA\",\n    id_country: \"USA\",\n    expected_document_types: [\"P\", \"ID\"],\n  }\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.CreateAsync(new SessionsCreateParams\n{\n    WorkflowId = \"11111111-2222-3333-4444-555555555555\",\n    VendorData = \"user-123\",\n    Callback = \"https://example.com/verification/callback\",\n    CallbackMethod = new SessionsCreateParamsCallbackMethod(\"both\"),\n    Metadata = new Dictionary<string, object> { [\"user_type\"] = \"premium\", [\"account_id\"] = \"ABC123\" },\n    Language = new SessionsCreateParamsLanguage(\"en\"),\n    ContactDetails = new SessionsCreateParamsContactDetails\n    {\n        Email = \"john.doe@example.com\",\n        SendNotificationEmails = true,\n        EmailLang = new SessionsCreateParamsContactDetailsEmailLang(\"en\"),\n        Phone = \"+14155552671\",\n    },\n    ExpectedDetails = new SessionsCreateParamsExpectedDetails\n    {\n        FirstName = \"John\",\n        LastName = \"Doe\",\n        DateOfBirth = \"1990-05-15\",\n        Nationality = \"USA\",\n        IdCountry = \"USA\",\n        ExpectedDocumentTypes = new SessionsCreateParamsExpectedDetailsExpectedDocumentTypes[] { \"P\", \"ID\" },\n    },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "workflow_id"
                ],
                "properties": {
                  "workflow_id": {
                    "type": "string",
                    "format": "uuid",
                    "description": "Pengidentifikasi stabil dari alur kerja yang menentukan langkah verifikasi mana yang akan dijalankan oleh sesi tersebut. Alur kerja dibuat dan dikelola di halaman [Workflows](/id/console/workflows) pada Konsol. `workflow_id` juga secara implisit memilih apakah sesi tersebut adalah KYC atau KYB.",
                    "example": "11111111-2222-3333-4444-555555555555",
                    "x-readme-id": "0.0"
                  },
                  "vendor_data": {
                    "type": "string",
                    "description": "Pengidentifikasi unik untuk pengguna yang sedang diverifikasi, seperti UUID, email, atau ID pengguna internal. Kolom ini digunakan untuk: (1) **Pengelompokan pengguna** — sesi dengan vendor_data yang sama ditautkan ke profil pengguna yang sama di tab Pengguna. (2) **Deteksi duplikat lintas-sesi** — saat memeriksa duplikasi wajah, dokumen, nomor telepon, email, alamat IP, atau sidik jari perangkat, sesi dengan vendor_data yang sama diperlakukan sebagai pengguna yang sama dan dikecualikan dari kecocokan. Tanpa vendor_data, setiap sesi diperlakukan sebagai pengguna unik dan semua potensi duplikat ditampilkan. Kami sangat menyarankan untuk selalu menyertakan vendor_data guna mengurangi derau dalam deteksi duplikat.",
                    "example": "user-123",
                    "x-readme-id": "0.1"
                  },
                  "multi_account_segment": {
                    "type": "string",
                    "maxLength": 64,
                    "description": "Realm deteksi duplikat opsional di dalam organisasi Anda. Pemeriksaan wajah duplikat hanya membandingkan sesi ini dengan sesi lain yang memiliki segmen yang sama, sehingga basis akun yang terpisah (akun pribadi dan bisnis, atau satu per sub-klien B2B) tidak menandai seseorang yang secara sah memiliki satu akun di masing-masing basis akun. Abaikan untuk menggunakan realm default tunggal, yang saat ini digunakan oleh setiap sesi. Pencocokan daftar blokir dan allowlist mengabaikan kolom ini.",
                    "example": "business-accounts"
                  },
                  "callback": {
                    "type": "string",
                    "description": "URL untuk mengarahkan pengguna setelah verifikasi selesai. Didit secara otomatis menambahkan `verificationSessionId` dan `status` (Approved, Declined, In Review) sebagai parameter kueri. Skema URL kustom (misalnya `myapp://`) didukung untuk callback seluler. Jika tidak disertakan, `callback_url` default milik alur kerja akan digunakan. Jika aplikasi memiliki domain yang diizinkan (`allowed_domains` pada `PATCH /v3/webhook/`), callback `http` atau `https` harus berada di salah satu origin tersebut (skema, host, dan port yang sama), jika tidak, permintaan gagal dengan 400 pada `callback`: `callback must be on one of the application's allowed domains: https://app.example.com`. Skema URL kustom selalu diterima.",
                    "example": "https://example.com/verification/callback",
                    "x-readme-id": "0.2"
                  },
                  "callback_method": {
                    "type": "string",
                    "description": "Menentukan perangkat mana yang harus menangani pengalihan ke URL callback yang diberikan. Gunakan `initiator` untuk mengalihkan hanya perangkat yang memulai alur, `completer` untuk perangkat yang menyelesaikannya, atau `both` untuk mengizinkan salah satu perangkat memicu callback. Jika Anda mendapati callback tidak terpicu secara andal, kami sarankan untuk menyetel nilai ini ke `both`.",
                    "enum": [
                      "initiator",
                      "completer",
                      "both"
                    ],
                    "default": "initiator",
                    "example": "both",
                    "x-readme-id": "0.3"
                  },
                  "metadata": {
                    "description": "JSON arbitrer yang disimpan bersama sesi dan dikembalikan dalam respons serta webhook. Nilai JSON apa pun diterima (objek, string, angka, array), tetapi objek JSON yang berisi pasangan kunci/nilai disarankan. Tidak ditampilkan kepada pengguna akhir. Gunakan ini untuk meneruskan ID korelasi Anda sendiri, varian A/B, atau konteks bisnis.",
                    "example": {
                      "user_type": "premium",
                      "account_id": "ABC123"
                    },
                    "x-readme-id": "0.4"
                  },
                  "tags": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "maxLength": 50
                    },
                    "maxItems": 10,
                    "description": "Tag yang ditambahkan ke sesi saat dibuat, berdasarkan nama. Hingga 10 tag, masing-masing hingga 50 karakter. Nama tidak membedakan huruf besar/kecil dan disimpan dalam huruf besar. Nama yang belum ada di aplikasi akan dibuat sebagai tag baru. Tag ditampilkan pada sesi di konsol, tempat Anda dapat memfilternya.",
                    "example": [
                      "VIP",
                      "ONBOARDING Q4"
                    ]
                  },
                  "language": {
                    "type": "string",
                    "description": "Kode bahasa (ISO 639-1) untuk antarmuka proses verifikasi. Mengontrol bahasa yang ditampilkan kepada pengguna akhir selama verifikasi. Jika tidak diberikan, bahasa browser akan terdeteksi dan digunakan secara otomatis. Periksa semua bahasa yang didukung [di sini](/id/integration/supported-languages).",
                    "enum": [
                      "en",
                      "ar",
                      "bg",
                      "bn",
                      "bs",
                      "ca",
                      "cnr",
                      "cs",
                      "da",
                      "de",
                      "el",
                      "es",
                      "et",
                      "fa",
                      "fi",
                      "fr",
                      "he",
                      "hi",
                      "hr",
                      "hu",
                      "hy",
                      "id",
                      "it",
                      "ja",
                      "ka",
                      "kk",
                      "ko",
                      "ky",
                      "lt",
                      "lv",
                      "mk",
                      "mn",
                      "ms",
                      "nl",
                      "no",
                      "pl",
                      "pt-BR",
                      "pt",
                      "ro",
                      "ru",
                      "sk",
                      "sl",
                      "so",
                      "sq",
                      "sr",
                      "sv",
                      "th",
                      "tr",
                      "uk",
                      "uz",
                      "vi",
                      "zh-CN",
                      "zh-TW",
                      "zh"
                    ],
                    "example": "en",
                    "x-readme-id": "0.5"
                  },
                  "contact_details": {
                    "type": "object",
                    "description": "Informasi kontak pengguna yang dapat digunakan untuk notifikasi, pra-pengisian formulir verifikasi, dan verifikasi telepon. Ini mencakup alamat email, bahasa pilihan untuk komunikasi, dan nomor telepon.",
                    "example": {
                      "email": "john.doe@example.com",
                      "send_notification_emails": true,
                      "email_lang": "en",
                      "phone": "+14155552671"
                    },
                    "properties": {
                      "email": {
                        "type": "string",
                        "format": "email",
                        "description": "Alamat email pengguna (misalnya, \"john.doe@example.com\") yang akan digunakan selama langkah [Verifikasi Email](/id/core-technology/email-verification/overview). Jika tidak diberikan, pengguna harus memberikannya selama alur verifikasi.",
                        "example": "john.doe@example.com",
                        "x-readme-id": "1.0"
                      },
                      "send_notification_emails": {
                        "type": "boolean",
                        "default": false,
                        "description": "Jika true dan email diberikan, Didit mengirimkan email awal \"Verifikasi identitas Anda\" secara asinkron saat sesi Verifikasi Pengguna (KYC) atau Verifikasi Bisnis (KYB) dibuat. Didit juga mengirimkan notifikasi status verifikasi untuk sesi yang memerlukan peninjauan manual ke alamat email yang diberikan (misalnya, dari 'In Review' ke 'Approved' atau 'Declined'). Hal ini membantu pengguna kembali ke aplikasi Anda setelah verifikasi mereka selesai. Jika Anda mengaktifkan White Label untuk sesi tersebut, email yang dikirim akan menggunakan White Label.",
                        "example": true,
                        "x-readme-id": "1.1"
                      },
                      "email_lang": {
                        "type": "string",
                        "description": "Kode bahasa (ISO 639-1) untuk notifikasi email. Mengontrol bahasa semua komunikasi email (misalnya, \"en\", \"es\", \"fr\"). Tidak ada default tersimpan — jika diabaikan, email undangan verifikasi akan beralih ke bahasa Inggris (`en`) pada saat pengiriman. Enum di bawah ini adalah snapshot; sumber kebenaran langsung untuk nilai yang diterima adalah dokumen [bahasa yang didukung](/id/integration/supported-languages) — selalu baca dokumen tersebut sebelum mengandalkan kode tertentu.",
                        "enum": [
                          "en",
                          "ar",
                          "bg",
                          "bn",
                          "bs",
                          "ca",
                          "cnr",
                          "cs",
                          "da",
                          "de",
                          "el",
                          "es",
                          "et",
                          "fa",
                          "fi",
                          "fr",
                          "he",
                          "hi",
                          "hr",
                          "hu",
                          "hy",
                          "id",
                          "it",
                          "ja",
                          "ka",
                          "kk",
                          "ko",
                          "ky",
                          "lt",
                          "lv",
                          "mk",
                          "mn",
                          "ms",
                          "nl",
                          "no",
                          "pl",
                          "pt-BR",
                          "pt",
                          "ro",
                          "ru",
                          "sk",
                          "sl",
                          "so",
                          "sq",
                          "sr",
                          "sv",
                          "th",
                          "tr",
                          "uk",
                          "uz",
                          "vi",
                          "zh-CN",
                          "zh-TW",
                          "zh"
                        ],
                        "example": "en",
                        "x-readme-id": "1.2"
                      },
                      "phone": {
                        "type": "string",
                        "description": "Nomor telepon dalam format E.164 (misalnya, \"+14155552671\") yang akan digunakan selama langkah [Verifikasi Telepon](/id/core-technology/phone-verification/overview). Jika tidak diberikan, pengguna harus memberikannya selama alur verifikasi. Diabaikan untuk alur kerja Verifikasi Bisnis (KYB). **Penting:** Nomor telepon ini hanya diterapkan jika merupakan nomor telepon E.164 yang valid. Jika nomor yang diberikan tidak valid atau tidak dapat diurai, nomor tersebut akan diabaikan dan pengguna akan dapat memasukkan nomor telepon valid apa pun selama langkah Verifikasi Telepon.",
                        "example": "+14155552671",
                        "x-readme-id": "1.3"
                      }
                    },
                    "x-readme-id": "0.4"
                  },
                  "expected_details": {
                    "type": "object",
                    "description": "Detail pengguna yang diharapkan yang digunakan untuk validasi silang terhadap data yang diekstraksi dari dokumen identitas pengguna, Bukti Alamat, dan langkah verifikasi lainnya. Ketidakcocokan dimunculkan sebagai peringatan pada keputusan; beberapa kolom (misalnya `id_country`, `expected_document_types`) juga mengubah alur bagi pengguna. Untuk alur kerja Verifikasi Bisnis (KYB), hanya kolom bisnis (`company_name`, `registry_country`, `registration_number`) yang digunakan — kolom-kolom ini mengisi otomatis pencarian registri perusahaan untuk pengguna — dan semua kolom tingkat orang diabaikan.",
                    "example": {
                      "first_name": "John",
                      "last_name": "Doe",
                      "date_of_birth": "1990-05-15",
                      "nationality": "USA",
                      "id_country": "USA",
                      "expected_document_types": [
                        "P",
                        "ID"
                      ]
                    },
                    "properties": {
                      "first_name": {
                        "type": "string",
                        "description": "Nama depan pengguna. Misalnya, `John`. Pencocokan menggunakan perbandingan fuzzy, dan Anda dapat menyesuaikan tingkat ketatnya dengan mengonfigurasi ambang batas skor kecocokan nama di Konsol untuk alur kerja Dokumen Identitas dan Bukti Alamat.",
                        "example": "John",
                        "x-readme-id": "1.0"
                      },
                      "last_name": {
                        "type": "string",
                        "description": "Nama belakang pengguna. Misalnya, `Doe`. Pencocokan menggunakan perbandingan fuzzy, dan Anda dapat menyesuaikan tingkat ketatnya dengan mengonfigurasi ambang batas skor kecocokan nama di Konsol untuk alur kerja Dokumen Identitas dan Bukti Alamat.",
                        "example": "Doe",
                        "x-readme-id": "1.1"
                      },
                      "date_of_birth": {
                        "type": "string",
                        "format": "date",
                        "description": "Tanggal lahir pengguna dengan format: YYYY-MM-DD. Misalnya, `1990-05-15`.",
                        "example": "1990-05-15",
                        "x-readme-id": "1.2"
                      },
                      "gender": {
                        "type": "string",
                        "nullable": true,
                        "enum": [
                          "M",
                          "F"
                        ],
                        "default": null,
                        "description": "Jenis kelamin pengguna. Harus berupa 'M', 'F', atau null.",
                        "example": "M",
                        "x-readme-id": "1.3"
                      },
                      "nationality": {
                        "type": "string",
                        "description": "Kode negara ISO 3166-1 alpha-3 yang mewakili negara asal pemohon. Misalnya, `USA`. Lihat [daftar lengkap kode negara yang didukung](https://docs.didit.me/id/core-technology/id-verification/supported-documents-id-verification#dokumen-yang-didukung-per-negara).",
                        "example": "USA",
                        "x-readme-id": "1.4"
                      },
                      "country": {
                        "type": "string",
                        "description": "Kode negara ISO 3166-1 alpha-3 yang digunakan sebagai cadangan untuk pemeriksaan ketidakcocokan negara Verifikasi Identitas dan Bukti Alamat. Wajib diisi jika `address` diberikan dan baik `id_country` maupun `poa_country` tidak diatur.",
                        "example": "USA",
                        "x-readme-id": "1.4.1"
                      },
                      "id_country": {
                        "type": "string",
                        "description": "Kode negara ISO 3166-1 alpha-3 yang mewakili negara yang diharapkan dari dokumen ID pemohon, yang mungkin berbeda dari kewarganegaraan. Misalnya, `GBR`. Mengambil prioritas di atas `country` untuk pemeriksaan ketidakcocokan negara Verifikasi Identitas. Lihat [daftar lengkap kode negara yang didukung](https://docs.didit.me/id/core-technology/id-verification/supported-documents-id-verification#dokumen-yang-didukung-per-negara).",
                        "example": "GBR",
                        "x-readme-id": "1.5"
                      },
                      "poa_country": {
                        "type": "string",
                        "description": "Kode negara ISO 3166-1 alpha-3 yang mewakili negara dokumen Bukti Alamat yang diharapkan. Misalnya, `USA`. Memiliki prioritas di atas `country` untuk pemeriksaan ketidakcocokan negara POA. Lihat [daftar lengkap kode negara yang didukung](https://docs.didit.me/id/core-technology/id-verification/supported-documents-id-verification#dokumen-yang-didukung-per-negara).",
                        "example": "USA",
                        "x-readme-id": "1.5.1"
                      },
                      "address": {
                        "type": "string",
                        "description": "Alamat dalam format yang dapat dibaca manusia, menyertakan sebanyak mungkin informasi. Misalnya, `123 Main St, San Francisco, CA 94105, USA`. Jika diberikan, Anda juga harus meneruskan `country` atau `poa_country`, jika tidak, permintaan gagal dengan `400`.",
                        "example": "123 Main St, San Francisco, CA 94105, USA",
                        "x-readme-id": "1.6"
                      },
                      "identification_number": {
                        "type": "string",
                        "description": "Nomor dokumen, nomor pribadi, atau nomor pajak pengguna. Misalnya, `123456789`.",
                        "example": "123456789",
                        "x-readme-id": "1.7"
                      },
                      "ip_address": {
                        "type": "string",
                        "description": "Alamat IP yang diharapkan untuk sesi, dalam format IPv4 atau IPv6. Jika alamat IP sebenarnya berbeda dari nilai ini, peringatan akan dicatat. Misalnya, `192.168.1.100` atau `2001:db8::1`.",
                        "example": "192.168.1.100",
                        "x-readme-id": "1.8"
                      },
                      "expected_document_types": {
                        "type": "array",
                        "description": "Membatasi jenis dokumen yang dapat ditunjukkan pengguna selama langkah verifikasi identitas (OCR). Jika diatur, layar pemilihan dokumen hanya menampilkan jenis yang diminta dan `documents_allowed` yang dikembalikan difilter sesuai pengaturan tersebut. Nilai tidak peka huruf besar/kecil dan dideduplikasi; nilai yang tidak dikenal ditolak dengan `400`. Kode yang diizinkan: `P` (paspor), `ID` (kartu identitas nasional), `DL` (SIM), `RP` (izin tinggal), `HIC` (kartu asuransi kesehatan), `TC` (kartu pajak), `SSC` (kartu jaminan sosial).",
                        "items": {
                          "type": "string",
                          "enum": [
                            "P",
                            "ID",
                            "DL",
                            "RP",
                            "HIC",
                            "TC",
                            "SSC"
                          ]
                        },
                        "example": [
                          "P",
                          "ID"
                        ],
                        "x-readme-id": "1.9"
                      },
                      "company_name": {
                        "type": "string",
                        "maxLength": 255,
                        "description": "Nama resmi yang diharapkan dari bisnis yang sedang diverifikasi. Misalnya, `Tesco PLC`. Mengisi otomatis kolom nama perusahaan pada pencarian registri di alur kerja Verifikasi Bisnis (KYB); jika `registration_number` juga disediakan, pencarian registri menggabungkan kedua pengidentifikasi. Diabaikan untuk alur kerja KYC.",
                        "example": "Tesco PLC",
                        "x-readme-id": "1.10"
                      },
                      "registry_country": {
                        "type": "string",
                        "maxLength": 10,
                        "description": "Kode ISO 3166-1 alpha-2 untuk negara tempat bisnis terdaftar di registri perusahaannya. Misalnya, `GB`. Jika registri perusahaan beroperasi di tingkat negara bagian atau provinsi, tambahkan kode subdivisi ISO 3166-2 sebagai `XX-YY`: `US-CA` menargetkan registri California. Format yang sama seperti `country_code` pada [API Pencarian Registri KYB](https://docs.didit.me/id/standalone-apis/kyb-registry-search). Memilih negara registri terlebih dahulu dalam alur kerja Verifikasi Bisnis (KYB); diabaikan untuk alur kerja KYC.",
                        "example": "US-CA",
                        "x-readme-id": "1.11"
                      },
                      "registration_number": {
                        "type": "string",
                        "maxLength": 100,
                        "description": "Nomor registrasi bisnis yang diharapkan di registri perusahaan. Misalnya, `00445790`. Mengisi otomatis kolom nomor registrasi pada pencarian registri di alur kerja Verifikasi Bisnis (KYB); jika `company_name` juga disediakan, pencarian registri menggabungkan kedua pengidentifikasi. Diabaikan untuk alur kerja KYC.",
                        "example": "00445790",
                        "x-readme-id": "1.12"
                      }
                    },
                    "x-readme-id": "0.5"
                  },
                  "portrait_image": {
                    "type": "string",
                    "format": "byte",
                    "description": "Gambar potret wajah pengguna akhir yang di-encode Base64 (maks 2MB; JPEG, PNG, WebP, atau TIFF). Digunakan sebagai gambar referensi untuk dicocokkan dengan tangkapan liveness saat alur kerja merupakan alur kerja `Biometric Authentication` dengan Pencocokan Wajah diaktifkan, atau alur kerja graf apa pun di mana Pencocokan Wajah berjalan sebelum Verifikasi Identitas (OCR). Opsional jika pengguna `vendor_data` sudah memiliki gambar wajah yang tersimpan: Didit menggunakannya kembali secara otomatis, ditentukan berdasarkan urutan prioritas: wajah liveness yang disetujui, foto chip ePassport, potret dokumen identitas, wajah profil yang didaftarkan secara manual (hanya wajah dari sesi yang disetujui atau wajah yang Anda daftarkan sendiri yang digunakan kembali). Jika diberikan, `portrait_image` selalu diutamakan daripada wajah yang tersimpan. Jika dihilangkan dan tidak ada wajah tersimpan yang ditemukan (atau `vendor_data` tidak dikirim), pembuatan sesi gagal dengan `400`. Diabaikan untuk jenis alur kerja lainnya.",
                    "example": "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=",
                    "x-readme-id": "0.6"
                  },
                  "sandbox_scenario": {
                    "type": "string",
                    "description": "Slug skenario khusus sandbox. Hanya diterima jika kunci API milik aplikasi mode sandbox; ditolak pada aplikasi produksi. Saat disetel, alur pembuatan akan menyematkan nilai ajaib yang dibundel skenario ke dalam kolom input sesi (contact_details, expected_details) sehingga penyedia tiruan menghasilkan hasil skenario tersebut melalui alur kerja nyata. Lihat katalog skenario di GET /v1/sandbox/scenarios/ atau [Sandbox & Data Uji](/id/integration/sandbox-testing). Anda juga dapat mengaktifkan (atau mengaktifkan ulang) skenario setelah pembuatan melalui POST /v3/session/{sessionId}/sandbox/arm/, selama sesi masih `Not Started`. Untuk pencarian non-dokumen, gunakan `lookup_partial_match`, `lookup_no_match`, atau `lookup_provider_error` untuk menguji anggaran percobaan dan fallback yang dikonfigurasi. Untuk dompet identitas, gunakan `wallet_cancelled`, `wallet_timeout`, atau `wallet_provider_error`; `approve` mensimulasikan dompet yang terverifikasi. Semua dompet katalog dapat diuji di sandbox, termasuk skema yang tidak tersedia di aplikasi produksi. Percobaan yang disimulasikan tidak dikenakan biaya.",
                    "example": "decline_document_expired"
                  },
                  "sign": {
                    "type": "object",
                    "description": "Input Tanda Tangan Elektronik untuk sesi ini. `documents` adalah dokumen yang akan ditandatangani, untuk alur kerja yang langkah Tanda Tangan Elektronik-nya mengambil dokumen dari sesi (`signature_documents_source` `session` atau `both`): hingga 20 dokumen dan total 50 MB. `field_values` mengisi kolom yang `prefill`-nya adalah `api.<key>`, baik pada dokumen alur kerja maupun sesi. Membuat sesi kembali untuk `workflow_id` dan `vendor_data` yang sama akan mengembalikan sesi yang tertunda; jika panggilan tersebut mengirimkan `sign`, dokumen, kolom, dan nilainya harus identik dengan yang pertama, dan perbedaan apa pun mengembalikan `400` dengan `{\"sign\": \"signature_document_changed\"}`. Lihat [Dokumen Tanda Tangan Elektronik](/id/sessions-api/create-session#dokumen-tanda-tangan-elektronik).",
                    "properties": {
                      "documents": {
                        "type": "array",
                        "minItems": 1,
                        "maxItems": 20,
                        "items": {
                          "$ref": "#/components/schemas/SessionSignDocument"
                        }
                      },
                      "field_values": {
                        "type": "object",
                        "description": "Nilai yang diindeks berdasarkan `<key>` dari setiap sumber pra-isi `api.<key>`: string sepanjang 1 hingga 500 karakter untuk kolom `text` dan `data`, boolean untuk `checkbox`. `400` dengan `field_value_unknown` untuk kunci yang tidak digunakan oleh kolom mana pun, `field_value_missing` untuk kolom wajib tanpa nilainya, dan `field_value_invalid` untuk nilai yang gagal dalam validasi kolomnya.",
                        "additionalProperties": {
                          "oneOf": [
                            {
                              "type": "string",
                              "minLength": 1,
                              "maxLength": 500
                            },
                            {
                              "type": "boolean"
                            }
                          ]
                        },
                        "example": {
                          "credit_limit": "3,000 EUR"
                        }
                      }
                    }
                  },
                  "user_state": {
                    "type": "string",
                    "maxLength": 16,
                    "description": "Tempat tinggal individu tersebut, jika Anda mengetahuinya: kode subdivisi ISO 3166-2 (`US-IL`, `ES-M`) atau kode atau nama negara bagian AS (`IL`, `Illinois`). Negara bagian yang hukumnya mewajibkan persetujuan biometrik eksplisit (Illinois, Texas, Colorado) membuat alur verifikasi memintanya sebelum mengambil wajah, dengan pemicu `declared_state`. Nilai yang tidak dikenali mengembalikan `400`. Lihat [Persetujuan biometrik](/id/getting-started/biometric-consent).",
                    "example": "US-IL"
                  },
                  "biometric_consent": {
                    "type": "object",
                    "description": "Persetujuan biometrik eksplisit yang telah Anda kumpulkan dari orang tersebut. Ini memenuhi persyaratan, sehingga alur verifikasi tidak meminta lagi, dan keputusan mencatatnya sebagai `status: \"given\"` dengan pemicu `customer_collected`. Jawaban yang sudah diberikan oleh orang tersebut dalam alur tidak pernah digantikan. Lihat [Persetujuan biometrik](/id/getting-started/biometric-consent).",
                    "required": [
                      "given_at",
                      "text_version"
                    ],
                    "properties": {
                      "given_at": {
                        "type": "string",
                        "format": "date-time",
                        "description": "Waktu pengguna memberikan persetujuan biometrik eksplisit (ISO 8601). Tidak boleh di masa mendatang."
                      },
                      "text_version": {
                        "type": "string",
                        "maxLength": 64,
                        "description": "ID versi dari teks persetujuan yang disetujui individu tersebut, dalam catatan Anda sendiri."
                      }
                    }
                  }
                },
                "example": {
                  "workflow_id": "11111111-2222-3333-4444-555555555555",
                  "vendor_data": "user-123",
                  "callback": "https://example.com/verification/callback",
                  "callback_method": "both",
                  "metadata": {
                    "user_type": "premium",
                    "account_id": "ABC123"
                  },
                  "language": "en",
                  "contact_details": {
                    "email": "john.doe@example.com",
                    "send_notification_emails": true,
                    "email_lang": "en",
                    "phone": "+14155552671"
                  },
                  "expected_details": {
                    "first_name": "John",
                    "last_name": "Doe",
                    "date_of_birth": "1990-05-15",
                    "id_country": "USA",
                    "expected_document_types": [
                      "P",
                      "ID"
                    ]
                  }
                }
              },
              "examples": {
                "Create KYC session": {
                  "summary": "Payload alur sukses lengkap untuk sesi Verifikasi Pengguna (KYC)",
                  "description": "Panggilan pembuatan realistis yang menggunakan setiap kolom yang umum diatur: pemilihan alur kerja, tautan vendor, perutean callback, metadata, pengaturan lokal, pra-pengisian kontak, dan detail pengguna yang diharapkan. Salin dan tempel ini langsung ke contoh cURL di atas.",
                  "value": {
                    "workflow_id": "11111111-2222-3333-4444-555555555555",
                    "vendor_data": "user-123",
                    "callback": "https://example.com/verification/callback",
                    "callback_method": "both",
                    "metadata": {
                      "user_type": "premium",
                      "account_id": "ABC123"
                    },
                    "language": "en",
                    "contact_details": {
                      "email": "john.doe@example.com",
                      "send_notification_emails": true,
                      "email_lang": "en",
                      "phone": "+14155552671"
                    },
                    "expected_details": {
                      "first_name": "John",
                      "last_name": "Doe",
                      "date_of_birth": "1990-05-15",
                      "nationality": "USA",
                      "id_country": "USA",
                      "expected_document_types": [
                        "P",
                        "ID"
                      ]
                    }
                  }
                },
                "Create KYB session": {
                  "summary": "Payload alur sukses untuk sesi Verifikasi Bisnis (KYB)",
                  "description": "Struktur yang sama dengan panggilan KYC — `workflow_id` adalah penentu yang menjadikan sesi sebagai KYB. `vendor_data` biasanya mereferensikan perusahaan di sistem Anda dan `contact_details.email` ditujukan kepada perwakilan hukum yang akan menyelesaikan alur; `expected_details` menerima kolom bisnis (`company_name`, `registry_country`, `registration_number`), yang digunakan untuk mengisi pencarian registri perusahaan terlebih dahulu; kolom tingkat individu dan `contact_details.phone` diabaikan untuk alur kerja KYB.",
                  "value": {
                    "workflow_id": "33333333-4444-5555-6666-777777777777",
                    "vendor_data": "company-acme-001",
                    "callback": "https://example.com/kyb/callback",
                    "callback_method": "both",
                    "metadata": {
                      "tier": "enterprise",
                      "company_id": "ACME-001"
                    },
                    "expected_details": {
                      "company_name": "Tesco PLC",
                      "registry_country": "GB",
                      "registration_number": "00445790"
                    },
                    "language": "en",
                    "contact_details": {
                      "email": "legal-rep@acme.example.com",
                      "send_notification_emails": true,
                      "email_lang": "en"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v3/session/imports/": {
      "post": {
        "summary": "Buat pekerjaan impor verifikasi",
        "description": "Buat tugas impor asinkron untuk sesi Verifikasi Pengguna historis, sesi Verifikasi Bisnis, catatan pemantauan transaksi, atau aturan status kustom alur kerja. Atur `source=provider` untuk bermigrasi dari penyedia lain: Didit membaca Sumsub, Onfido, Persona, dan ComplyCube dengan kunci baca-saja Anda, membaca catatan Veriff, iDenfy, dan MetaMap berdasarkan ID yang Anda unggah di `file`, serta mengimpor file ekspor dalam format Didit untuk penyedia lainnya. ID catatan diberi namespace berdasarkan penyedia (`sumsub:<id>`) sehingga eksekusi ulang akan melewati semua yang sudah ada di Didit, dan catatan yang diimpor melalui file dengan ID penyedia tanpa namespace juga dikenali, di kedua arah, sehingga beralih antara impor file dan migrasi penyedia tidak akan pernah mengimpor catatan dua kali. Sebuah aplikasi dapat menjalankan hingga 4 tugas impor sekaligus; tugas yang terputus oleh deploy atau restart worker akan berlanjut secara otomatis dari baris terakhir yang diimpor. Impor dinonaktifkan secara default dan harus diaktifkan per organisasi oleh Didit.",
        "operationId": "post_v3_session_imports_create",
        "x-didit-sdk": {
          "resource": "sessions.imports",
          "method": "create",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Sessions"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "properties": {
                  "import_type": {
                    "type": "string",
                    "enum": [
                      "user_verification",
                      "business_verification",
                      "status_rules",
                      "transactions"
                    ],
                    "default": "user_verification",
                    "description": "Apa yang akan diimpor: sesi Verifikasi Pengguna historis, sesi Verifikasi Bisnis (KYB) historis, aturan status kustom alur kerja, atau catatan pemantauan transaksi historis."
                  },
                  "workflow_id": {
                    "type": "string",
                    "format": "uuid",
                    "description": "UUID alur kerja tempat sesi yang diimpor atau aturan status harus ditautkan. Wajib diisi untuk user_verification, business_verification, dan status_rules. Abaikan untuk transaksi."
                  },
                  "source_format": {
                    "type": "string",
                    "enum": [
                      "csv",
                      "ndjson"
                    ],
                    "description": "Opsional. Disimpulkan dari ekstensi file yang diunggah jika tidak diberikan."
                  },
                  "file": {
                    "type": "string",
                    "format": "binary",
                    "description": "File CSV atau NDJSON kanonis. Gunakan NDJSON untuk impor berukuran besar. Ukuran unggahan maksimum 25 MB (gunakan `source_file_url` untuk file yang lebih besar). Saling eksklusif dengan `source_file_url`."
                  },
                  "source_file_url": {
                    "type": "string",
                    "format": "uri",
                    "description": "Alternatif untuk unggahan file. Harus berupa URL HTTPS yang mengarah ke alamat publik (jaringan privat/loopback ditolak). Saling eksklusif dengan `file`."
                  },
                  "source": {
                    "type": "string",
                    "enum": [
                      "file",
                      "provider"
                    ],
                    "description": "`provider` menandakan ini adalah migrasi dari penyedia verifikasi identitas lain. Jangan sertakan untuk impor file."
                  },
                  "provider": {
                    "type": "string",
                    "enum": [
                      "sumsub",
                      "jumio",
                      "veriff",
                      "onfido",
                      "persona",
                      "metamap",
                      "socure",
                      "idnow",
                      "shufti",
                      "idenfy",
                      "ondato",
                      "trulioo",
                      "au10tix",
                      "complycube",
                      "other"
                    ],
                    "description": "Sumber migrasi, dari `GET /v3/session/imports/providers/`. Wajib diisi jika `source` adalah `provider`."
                  },
                  "credentials": {
                    "type": "object",
                    "additionalProperties": {
                      "type": "string"
                    },
                    "description": "Kunci hanya-baca penyedia, dengan nama kolom yang tercantum dalam `credential_fields`. Dienkripsi saat disimpan, tidak pernah dikembalikan, dan dihapus saat impor selesai. Kirim sebagai string JSON dalam multipart."
                  },
                  "options": {
                    "type": "object",
                    "properties": {
                      "region": {
                        "type": "string",
                        "description": "Wilayah penyedia, salah satu dari `regions` miliknya (Onfido: `eu`, `us`, `ca`)."
                      }
                    }
                  },
                  "status_mapping": {
                    "type": "object",
                    "additionalProperties": {
                      "type": "string",
                      "enum": [
                        "Approved",
                        "Declined",
                        "In Review",
                        "Expired",
                        "Not Finished",
                        "Abandoned"
                      ]
                    },
                    "description": "Pengeditan pada pemetaan status default penyedia: status sumber ke status Didit. `Not Finished` dan `Abandoned` dilewati dan dihitung, tidak pernah diimpor."
                  },
                  "dry_run": {
                    "type": "boolean",
                    "default": false,
                    "description": "Hitung apa yang akan diimpor oleh migrasi (berdasarkan status, sudah ada di Didit, orang yang sama, belum selesai) dan tidak menulis apa pun. Pekerjaan berakhir dengan status `READY`; mulai dengan `POST /v3/session/imports/{importId}/start/`."
                  },
                  "face_templates": {
                    "type": "boolean",
                    "default": false,
                    "description": "Buat templat wajah dari swafoto yang diimpor dan cari terhadap wajah serta daftar blokir aplikasi. Kecocokan hanya ditandai untuk ditinjau. Memerlukan `lawful_basis_confirmed`."
                  },
                  "lawful_basis_confirmed": {
                    "type": "boolean",
                    "default": false,
                    "description": "Mengonfirmasi bahwa Anda memiliki dasar hukum untuk membagikan swafoto ini kepada Didit sebagai pemroses."
                  }
                }
              }
            },
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "source_file_url"
                ],
                "properties": {
                  "import_type": {
                    "type": "string",
                    "enum": [
                      "user_verification",
                      "business_verification",
                      "status_rules",
                      "transactions"
                    ],
                    "default": "user_verification",
                    "description": "Apa yang akan diimpor: sesi Verifikasi Pengguna historis, sesi Verifikasi Bisnis (KYB) historis, aturan status kustom alur kerja, atau catatan pemantauan transaksi historis."
                  },
                  "workflow_id": {
                    "type": "string",
                    "format": "uuid",
                    "description": "UUID alur kerja tempat sesi yang diimpor atau aturan status harus ditautkan. Wajib diisi untuk user_verification, business_verification, dan status_rules. Abaikan untuk transaksi."
                  },
                  "source_format": {
                    "type": "string",
                    "enum": [
                      "csv",
                      "ndjson"
                    ],
                    "description": "Opsional. Disimpulkan dari ekstensi file URL jika tidak diberikan."
                  },
                  "source_file_url": {
                    "type": "string",
                    "format": "uri",
                    "description": "Alternatif untuk unggahan file. Harus berupa URL HTTPS yang mengarah ke alamat publik (jaringan privat/loopback ditolak). Saling eksklusif dengan `file`."
                  },
                  "source": {
                    "type": "string",
                    "enum": [
                      "file",
                      "provider"
                    ],
                    "description": "`provider` menandakan ini adalah migrasi dari penyedia verifikasi identitas lain. Jangan sertakan untuk impor file."
                  },
                  "provider": {
                    "type": "string",
                    "enum": [
                      "sumsub",
                      "jumio",
                      "veriff",
                      "onfido",
                      "persona",
                      "metamap",
                      "socure",
                      "idnow",
                      "shufti",
                      "idenfy",
                      "ondato",
                      "trulioo",
                      "au10tix",
                      "complycube",
                      "other"
                    ],
                    "description": "Sumber migrasi, dari `GET /v3/session/imports/providers/`. Wajib diisi jika `source` adalah `provider`."
                  },
                  "credentials": {
                    "type": "object",
                    "additionalProperties": {
                      "type": "string"
                    },
                    "description": "Kunci hanya-baca penyedia, dengan nama kolom yang tercantum dalam `credential_fields`. Dienkripsi saat disimpan, tidak pernah dikembalikan, dan dihapus saat impor selesai. Kirim sebagai string JSON dalam multipart."
                  },
                  "options": {
                    "type": "object",
                    "properties": {
                      "region": {
                        "type": "string",
                        "description": "Wilayah penyedia, salah satu dari `regions` miliknya (Onfido: `eu`, `us`, `ca`)."
                      }
                    }
                  },
                  "status_mapping": {
                    "type": "object",
                    "additionalProperties": {
                      "type": "string",
                      "enum": [
                        "Approved",
                        "Declined",
                        "In Review",
                        "Expired",
                        "Not Finished",
                        "Abandoned"
                      ]
                    },
                    "description": "Pengeditan pada pemetaan status default penyedia: status sumber ke status Didit. `Not Finished` dan `Abandoned` dilewati dan dihitung, tidak pernah diimpor."
                  },
                  "dry_run": {
                    "type": "boolean",
                    "default": false,
                    "description": "Hitung apa yang akan diimpor oleh migrasi (berdasarkan status, sudah ada di Didit, orang yang sama, belum selesai) dan tidak menulis apa pun. Pekerjaan berakhir dengan status `READY`; mulai dengan `POST /v3/session/imports/{importId}/start/`."
                  },
                  "face_templates": {
                    "type": "boolean",
                    "default": false,
                    "description": "Buat templat wajah dari swafoto yang diimpor dan cari terhadap wajah serta daftar blokir aplikasi. Kecocokan hanya ditandai untuk ditinjau. Memerlukan `lawful_basis_confirmed`."
                  },
                  "lawful_basis_confirmed": {
                    "type": "boolean",
                    "default": false,
                    "description": "Mengonfirmasi bahwa Anda memiliki dasar hukum untuk membagikan swafoto ini kepada Didit sebagai pemroses."
                  }
                }
              },
              "examples": {
                "URL-based import": {
                  "value": {
                    "import_type": "user_verification",
                    "workflow_id": "9f9b1234-aaaa-bbbb-cccc-1234567890ab",
                    "source_file_url": "https://files.example.com/exports/sessions.ndjson"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Pekerjaan impor diterima. Lakukan polling pada `uuid` yang dikembalikan hingga `status` menjadi `COMPLETED` atau `FAILED`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SessionImportJob"
                },
                "examples": {
                  "Job accepted": {
                    "value": {
                      "uuid": "3f9c1a2b-4d5e-4f60-8a7b-9c0d1e2f3a4b",
                      "status": "PENDING",
                      "import_type": "user_verification",
                      "source_format": "ndjson",
                      "source_filename": "sessions.ndjson",
                      "total_rows": 0,
                      "processed_rows": 0,
                      "checkpoint_row": 0,
                      "created_count": 0,
                      "updated_count": 0,
                      "skipped_count": 0,
                      "failed_count": 0,
                      "total_media_bytes": 0,
                      "last_error": null,
                      "created_at": "2026-05-17T08:42:11Z",
                      "updated_at": "2026-05-17T08:42:11Z",
                      "started_at": null,
                      "completed_at": null
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Alur kerja, tipe file, ukuran file, URL sumber, atau kombinasi selektor tidak valid. Migrasi yang kuncinya ditolak penyedia akan merespons `code` (`invalid_credentials`, `missing_permission`, `wrong_region`, `provider_unavailable`, `rate_limited`, `ids_required`, `record_not_found`), `missing_permissions`, dan `suggested_region`.",
            "content": {
              "application/json": {
                "examples": {
                  "Invalid workflow": {
                    "value": {
                      "workflow_id": [
                        "Invalid workflow_id."
                      ]
                    }
                  },
                  "Workflow required": {
                    "value": {
                      "workflow_id": [
                        "This field is required for this import type."
                      ]
                    }
                  },
                  "Wrong file type": {
                    "value": {
                      "file": [
                        "Only CSV and NDJSON files are supported."
                      ]
                    }
                  },
                  "File too large": {
                    "value": {
                      "file": [
                        "Import file exceeds the maximum allowed size."
                      ]
                    }
                  },
                  "No source": {
                    "value": {
                      "file": [
                        "Upload a file or provide source_file_url."
                      ]
                    }
                  },
                  "Both sources": {
                    "value": {
                      "file": [
                        "Use either file or source_file_url, not both."
                      ]
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Impor tidak diaktifkan, aplikasi sandbox, atau kunci API tidak ada (kunci yang salah, dicabut, atau kedaluwarsa mendapatkan `401`). Impor verifikasi dinonaktifkan secara default dan harus diaktifkan per organisasi oleh Didit.",
            "content": {
              "application/json": {
                "examples": {
                  "Imports not enabled": {
                    "value": {
                      "detail": "Verification imports are not enabled for this organization."
                    }
                  },
                  "Sandbox": {
                    "value": {
                      "detail": "Verification imports are not enabled for sandbox applications."
                    }
                  },
                  "Bad API key": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Aplikasi sudah memiliki 4 tugas impor aktif (PENDING/PROCESSING/PAUSED), batas maksimum yang dapat dijalankan secara bersamaan. Tunggu hingga salah satunya selesai sebelum memulai yang lain.",
            "content": {
              "application/json": {
                "examples": {
                  "Active job": {
                    "value": {
                      "detail": "This application already has 4 active import jobs, the most it can run at once. Wait for one to finish before starting another."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.imports.create(\n    import_type=\"user_verification\",\n    workflow_id=\"9f9b1234-aaaa-bbbb-cccc-1234567890ab\",\n    source_file_url=\"https://files.example.com/exports/sessions.ndjson\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.imports.create({\n  import_type: \"user_verification\",\n  workflow_id: \"9f9b1234-aaaa-bbbb-cccc-1234567890ab\",\n  source_file_url: \"https://files.example.com/exports/sessions.ndjson\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.Imports.Create(ctx, didit.SessionsImportsCreateParams{\n\tImportType:    didit.Some(didit.SessionsImportsCreateParamsImportType(\"user_verification\")),\n\tWorkflowID:    didit.String(\"9f9b1234-aaaa-bbbb-cccc-1234567890ab\"),\n\tSourceFileURL: didit.String(\"https://files.example.com/exports/sessions.ndjson\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.SessionsImportsCreateParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().imports().create(SessionsImportsCreateParams.builder()\n        .importType(SessionsImportsCreateParams.ImportType.of(\"user_verification\"))\n        .workflowId(\"9f9b1234-aaaa-bbbb-cccc-1234567890ab\")\n        .sourceFileUrl(\"https://files.example.com/exports/sessions.ndjson\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->sessions->imports->create([\n    'import_type' => 'user_verification',\n    'workflow_id' => '9f9b1234-aaaa-bbbb-cccc-1234567890ab',\n    'source_file_url' => 'https://files.example.com/exports/sessions.ndjson',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.imports.create(\n  import_type: \"user_verification\",\n  workflow_id: \"9f9b1234-aaaa-bbbb-cccc-1234567890ab\",\n  source_file_url: \"https://files.example.com/exports/sessions.ndjson\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.Imports.CreateAsync(new SessionsImportsCreateParams\n{\n    ImportType = new SessionsImportsCreateParamsImportType(\"user_verification\"),\n    WorkflowId = \"9f9b1234-aaaa-bbbb-cccc-1234567890ab\",\n    SourceFileUrl = \"https://files.example.com/exports/sessions.ndjson\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/session/imports/template/": {
      "get": {
        "summary": "Unduh templat impor verifikasi",
        "description": "Unduh header CSV kanonis untuk impor verifikasi. Kumpulan kolom ditentukan oleh `import_type`. Kolom pertama dari templat sesi adalah kunci idempotensi `external_id`.",
        "operationId": "get_v3_session_imports_template",
        "x-didit-sdk": {
          "resource": "sessions.imports",
          "method": "retrieve_template",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Sessions"
        ],
        "parameters": [
          {
            "name": "import_type",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "user_verification",
                "business_verification",
                "status_rules",
                "transactions"
              ],
              "default": "user_verification"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "File templat CSV.",
            "content": {
              "text/csv": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "403": {
            "description": "Kunci API tidak ada, tidak valid, atau dicabut, atau kunci tersebut tidak dapat mengunduh templat impor. Kunci yang tidak ada mengembalikan `403`; kunci yang salah, dicabut, atau kedaluwarsa mengembalikan `401`.",
            "content": {
              "application/json": {
                "examples": {
                  "Forbidden": {
                    "summary": "Kunci API tidak ada, tidak valid, atau dicabut",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\ncontent = client.sessions.imports.retrieve_template()\nwith open(\"download.csv\", \"wb\") as file:\n    file.write(content)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import { writeFile } from \"node:fs/promises\";\nimport Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst content = await didit.sessions.imports.retrieveTemplate();\nawait writeFile(\"download.csv\", Buffer.from(await content.arrayBuffer()));"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresp, err := client.Sessions.Imports.RetrieveTemplate(ctx, didit.SessionsImportsRetrieveTemplateParams{})\nif err != nil {\n\tlog.Fatal(err)\n}\ndefer resp.Body.Close()\nfile, err := os.Create(\"download.csv\")\nif err != nil {\n\tlog.Fatal(err)\n}\ndefer file.Close()\nif _, err := io.Copy(file, resp.Body); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.nio.file.Path;\nimport me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nclient.sessions().imports().retrieveTemplate()\n        .writeTo(Path.of(\"download.csv\"));"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$content = $didit->sessions->imports->retrieveTemplate();\n$content->saveTo('download.csv');"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ncontent = didit.sessions.imports.retrieve_template\nFile.binwrite(\"download.csv\", content)"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar content = await client.Sessions.Imports.RetrieveTemplateAsync();\nawait content.SaveToAsync(\"download.csv\");"
          }
        ]
      }
    },
    "/v3/session/imports/{importId}/": {
      "get": {
        "summary": "Ambil tugas impor verifikasi",
        "description": "Ambil penghitung progres impor dan status akhir untuk satu tugas. Lakukan polling hingga `status` menjadi `COMPLETED` atau `FAILED`; `failed_count` > 0 berarti beberapa baris ditolak — buat daftarnya melalui endpoint error.",
        "operationId": "get_v3_session_imports_retrieve",
        "x-didit-sdk": {
          "resource": "sessions.imports",
          "method": "retrieve",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Sessions"
        ],
        "parameters": [
          {
            "name": "importId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Status pekerjaan impor.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SessionImportJob"
                }
              }
            }
          },
          "404": {
            "description": "Pekerjaan impor tidak ditemukan untuk aplikasi ini.",
            "content": {
              "application/json": {
                "examples": {
                  "Not found": {
                    "value": {
                      "detail": "Not found."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Kunci API tidak ada, tidak valid, atau dicabut, atau kunci tersebut tidak dapat membaca tugas impor untuk aplikasi ini. Kunci yang tidak ada mengembalikan `403`; kunci yang salah, dicabut, atau kedaluwarsa mengembalikan `401`.",
            "content": {
              "application/json": {
                "examples": {
                  "Forbidden": {
                    "summary": "Kunci API tidak ada, tidak valid, atau dicabut",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.imports.retrieve(\n    \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.imports.retrieve(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.Imports.Retrieve(ctx, \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().imports().retrieve(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->sessions->imports->retrieve('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.imports.retrieve(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.Imports.RetrieveAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/session/imports/{importId}/errors/": {
      "get": {
        "summary": "Daftar kesalahan baris impor verifikasi",
        "description": "Mencantumkan daftar error tingkat baris untuk tugas impor verifikasi, diurutkan berdasarkan `row_number`. Gunakan endpoint ini untuk menghasilkan file untuk percobaan ulang yang telah diperbaiki dan hanya berisi baris yang gagal.",
        "operationId": "get_v3_session_imports_errors",
        "x-didit-sdk": {
          "resource": "sessions.imports",
          "method": "list_errors",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Sessions"
        ],
        "parameters": [
          {
            "name": "importId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 50,
              "minimum": 1
            },
            "description": "Ukuran halaman. Nilai default-nya 50 jika dihilangkan."
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 0
            },
            "description": "Offset berbasis nol dari rekaman pertama yang dikembalikan."
          }
        ],
        "responses": {
          "200": {
            "description": "Kesalahan baris terpaginasi.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "count": {
                      "type": "integer",
                      "description": "Jumlah baris error — tepat hingga 100, dibatasi pada 100 setelahnya. Andalkan `next` yang bernilai `null` untuk mendeteksi halaman terakhir."
                    },
                    "next": {
                      "type": "string",
                      "nullable": true,
                      "description": "URL absolut halaman berikutnya, atau `null` di halaman terakhir."
                    },
                    "previous": {
                      "type": "string",
                      "nullable": true,
                      "description": "URL absolut halaman sebelumnya, atau `null` di halaman pertama."
                    },
                    "results": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/SessionImportError"
                      }
                    }
                  }
                },
                "examples": {
                  "Row errors": {
                    "value": {
                      "count": 1,
                      "next": null,
                      "previous": null,
                      "results": [
                        {
                          "uuid": "5a6b7c8d-9e0f-4a1b-8c2d-3e4f5a6b7c8d",
                          "row_number": 17,
                          "external_id": "ext-000017",
                          "error": "status: invalid value 'unknown_status'",
                          "raw_row": {
                            "external_id": "ext-000017",
                            "status": "unknown_status",
                            "first_name": "Jane"
                          },
                          "created_at": "2026-05-17T08:44:02Z"
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Pekerjaan impor tidak ditemukan untuk aplikasi ini.",
            "content": {
              "application/json": {
                "examples": {
                  "Not found": {
                    "value": {
                      "detail": "Not found."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Kunci API tidak ada, tidak valid, atau dicabut, atau kunci tersebut tidak dapat membaca tugas impor untuk aplikasi ini. Kunci yang tidak ada mengembalikan `403`; kunci yang salah, dicabut, atau kedaluwarsa mengembalikan `401`.",
            "content": {
              "application/json": {
                "examples": {
                  "Forbidden": {
                    "summary": "Kunci API tidak ada, tidak valid, atau dicabut",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nfor item in client.sessions.imports.list_errors(\n    \"11111111-2222-3333-4444-555555555555\",\n):\n    print(item)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nfor await (const item of didit.sessions.imports.listErrors(\"11111111-2222-3333-4444-555555555555\")) {\n  console.log(item);\n}"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\niter := client.Sessions.Imports.ListErrorsAutoPaging(ctx, \"11111111-2222-3333-4444-555555555555\", didit.SessionsImportsListErrorsParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nfor (var item : client.sessions().imports().listErrors(\"11111111-2222-3333-4444-555555555555\")) {\n    System.out.println(item);\n}"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\nforeach ($didit->sessions->imports->listErrors('11111111-2222-3333-4444-555555555555') as $item) {\n    print_r($item->toArray());\n}"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.sessions.imports.list_errors(\"11111111-2222-3333-4444-555555555555\").auto_paging_each do |item|\n  puts item.to_h\nend"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.Sessions.Imports.ListErrorsAsync(\"11111111-2222-3333-4444-555555555555\"))\n{\n    Console.WriteLine(JsonSerializer.Serialize(item));\n}"
          }
        ]
      }
    },
    "/v3/session/{sessionId}/decision/": {
      "get": {
        "summary": "Ambil keputusan lengkap untuk sesi verifikasi",
        "description": "Ambil laporan keputusan lengkap untuk suatu sesi verifikasi — `status` sesi yang digabungkan ditambah satu laporan per fitur verifikasi yang dijalankan alur kerja. Ini adalah endpoint baca kanonis untuk sesi Verifikasi Pengguna (KYC) maupun Verifikasi Bisnis (KYB): path yang sama melayani keduanya, dan diskriminator `session_kind` tingkat atas memberi tahu Anda bentuk mana yang Anda terima (`\"user\"` atau `\"business\"`).\n\n**Setiap laporan fitur berupa array berbentuk jamak.** Alur kerja V3 adalah graf yang dapat menjalankan fitur yang sama lebih dari sekali, sehingga setiap blok (`id_verifications`, `nfc_verifications`, `liveness_checks`, `face_matches`, `poa_verifications`, `document_ai_documents`, `phone_verifications`, `email_verifications`, `aml_screenings`, `ip_analyses`, `database_validations`, `questionnaire_responses`) adalah array JSON yang setiap itemnya memiliki `node_id` untuk mengidentifikasi node graf alur kerja yang menghasilkannya. Baca NFC sebagai `response.nfc_verifications[0]` — jangan pernah sebagai kolom tunggal `nfc`. Suatu blok bernilai `null` sampai alur kerja menjalankan fitur tersebut setidaknya satu kali; fitur yang tidak disertakan dalam alur kerja tidak akan pernah muncul dengan data. Hasil Tanda Tangan Elektronik ada di `signatures`, yang hanya ada ketika alur kerja memiliki langkah Tanda Tangan Elektronik.\n\n**Kapan harus memanggil.** Pola yang disarankan berbasis event: tunggu webhook `status.updated` yang terpicu saat sesi mencapai keputusan (`Approved`, `Declined`, `In Review`), lalu panggil endpoint ini sekali untuk mengambil laporan lengkap. Polling juga dapat berfungsi — endpoint dapat dipanggil pada titik mana pun dalam siklus hidup sesi dan mengembalikan data yang dihasilkan sejauh ini — tetapi menunggu webhook lalu mengambil laporan lebih hemat dan lebih cepat. URL media dalam respons (gambar dokumen, video, PDF) adalah tautan yang telah ditandatangani sebelumnya dan berumur pendek: ambil segera atau minta ulang keputusan untuk mendapatkan yang baru, dan jangan menyimpannya sebagai referensi jangka panjang.\n\n**Status.** `status` tingkat atas adalah status siklus hidup sesi (`Not Started`, `In Progress`, `Awaiting User`, `In Review`, `Approved`, `Declined`, `Resubmitted`, `Expired`, `Kyc Expired`, `Abandoned`). Setiap item fitur juga memiliki `status` tingkat fiturnya sendiri (`Not Finished`, `Approved`, `Declined`, `In Review`, ...). Suatu sesi dapat berstatus `Approved` secara keseluruhan sementara fitur individual berstatus `In Review`, bergantung pada aturan keputusan alur kerja.\n\n**Autentikasi dan visibilitas.** Lakukan autentikasi dengan kunci API aplikasi di header `x-api-key` (token Bearer pengguna konsol dengan izin `read:sessions` juga berfungsi). Hanya sesi yang dimiliki oleh aplikasi terautentikasi yang terlihat. Jika alur kerja Anda membatasi atribut respons, kolom yang tidak diizinkan di dalam item fitur akan dikembalikan sebagai `null` sedangkan `status`, `warnings`, dan `node_id` selalu dipertahankan.\n\n**Batas laju.** Permintaan GET dibatasi hingga 600 per menit per kunci API. Melebihi batas akan mengembalikan `429` dengan header `Retry-After` dan `X-RateLimit-*`.",
        "operationId": "get_v3_session_decision",
        "x-didit-sdk": {
          "resource": "sessions",
          "method": "retrieve_decision",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Sessions"
        ],
        "responses": {
          "200": {
            "description": "Laporan keputusan lengkap. `session_kind` membedakan dua bentuk: sesi `user` memuat array fitur KYC yang ditampilkan di bawah; sesi `business` justru memuat `registry_checks`, `document_verifications`, dan `key_people_checks` bersamaan dengan array bersama. Array fitur bernilai `null` sampai alur kerja menjalankan fitur tersebut; URL media adalah tautan bertanda tangan yang berlaku singkat.",
            "content": {
              "application/json": {
                "examples": {
                  "Example": {
                    "summary": "Contoh Lengkap",
                    "value": {
                      "session_id": "11111111-2222-3333-4444-555555555555",
                      "session_kind": "user",
                      "session_number": 43762,
                      "session_url": "https://verify.didit.me/session/11111111-2222-3333-4444-555555555555",
                      "status": "In Review",
                      "environment": "live",
                      "workflow_id": "11111111-2222-3333-4444-555555555555",
                      "features": [
                        "ID_VERIFICATION",
                        "NFC",
                        "LIVENESS",
                        "FACE_MATCH",
                        "POA",
                        "PHONE",
                        "DATABASE_VALIDATION",
                        "AML",
                        "IP_ANALYSIS"
                      ],
                      "vendor_data": "11111111-1111-1111-1111-111111111111",
                      "metadata": {
                        "user_type": "premium",
                        "account_id": "ABC123"
                      },
                      "expected_details": {
                        "first_name": "Carmen",
                        "last_name": "Española Española"
                      },
                      "contact_details": {
                        "email": "carmen@example.com",
                        "email_lang": "es",
                        "send_notification_emails": false,
                        "phone": null
                      },
                      "callback": "https://verify.didit.me/",
                      "id_verifications": [
                        {
                          "node_id": "feature_ocr_1",
                          "status": "Approved",
                          "document_type": "Identity Card",
                          "document_subtype": "ID_CARD_GENERIC",
                          "document_number": "CAA000000",
                          "personal_number": "99999999R",
                          "portrait_image": "https://<media-host>/portrait.jpg",
                          "front_image": "https://<media-host>/front.jpg",
                          "front_video": "https://<media-host>/front.mp4",
                          "back_image": "https://<media-host>/back.jpg",
                          "back_video": "https://<media-host>/back.mp4",
                          "full_front_image": "https://<media-host>/full_front.jpg",
                          "full_back_image": "https://<media-host>/full_back.jpg",
                          "front_image_camera_front": "https://<media-host>/front_camera_front.jpg",
                          "back_image_camera_front": "https://<media-host>/back_camera_front.jpg",
                          "date_of_birth": "1980-01-01",
                          "age": 45,
                          "expiration_date": "2031-06-02",
                          "date_of_issue": "2021-06-02",
                          "issuing_state": "ESP",
                          "issuing_state_name": "Spain",
                          "first_name": "Carmen",
                          "last_name": "Española Española",
                          "full_name": "Carmen Española Española",
                          "gender": "F",
                          "address": "Avda de Madrid 34, Madrid, Madrid",
                          "formatted_address": "Avda de Madrid 34, Madrid, Madrid 28822, Spain",
                          "place_of_birth": "Madrid",
                          "marital_status": "Single",
                          "nationality": "ESP",
                          "extra_fields": {
                            "dl_categories": [],
                            "blood_group": null
                          },
                          "mrz": {
                            "surname": "ESPANOLA ESPANOLA",
                            "name": "CARMEN",
                            "country": "ESP",
                            "nationality": "ESP",
                            "birth_date": "800101",
                            "expiry_date": "310602",
                            "sex": "F",
                            "document_type": "ID",
                            "document_number": "CAA000000",
                            "optional_data": "99999999R",
                            "optional_data_2": "",
                            "birth_date_hash": "4",
                            "expiry_date_hash": "8",
                            "document_number_hash": "4",
                            "final_hash": "1",
                            "personal_number": "99999999R",
                            "warnings": [],
                            "errors": [],
                            "mrz_type": "TD1",
                            "mrz_string": "IDESPCAA000000499999999R<<<<<<\n8001014F3106028ESP<<<<<<<<<<<1\nESPANOLA<ESPANOLA<<CARMEN<<<<<",
                            "mrz_key": "CAA000000480010143106028"
                          },
                          "parsed_address": {
                            "city": "Madrid",
                            "label": "Spain ID Card Address",
                            "region": "Madrid",
                            "country": "ES",
                            "category": "Residential",
                            "street_1": "Avda de Madrid 34",
                            "street_2": null,
                            "is_verified": true,
                            "postal_code": "28822",
                            "raw_results": {
                              "types": [
                                "street_address"
                              ],
                              "geometry": {
                                "location": {
                                  "lat": 37.4222804,
                                  "lng": -122.0843428
                                },
                                "viewport": {
                                  "northeast": {
                                    "lat": 37.4237349802915,
                                    "lng": -122.083183169709
                                  },
                                  "southwest": {
                                    "lat": 37.4210370197085,
                                    "lng": -122.085881130292
                                  }
                                },
                                "location_type": "ROOFTOP"
                              },
                              "place_id": "ChIJN1t_tDeuEmsRUsoyG83frY4",
                              "formatted_address": "Avda de Madrid 34, 28822 Madrid, Spain",
                              "navigation_points": [
                                {
                                  "location": {
                                    "latitude": 37.4222804,
                                    "longitude": -122.0843428
                                  }
                                }
                              ],
                              "address_components": [
                                {
                                  "types": [
                                    "street_number"
                                  ],
                                  "long_name": "34",
                                  "short_name": "34"
                                },
                                {
                                  "types": [
                                    "route"
                                  ],
                                  "long_name": "Avda de Madrid",
                                  "short_name": "Avda de Madrid"
                                },
                                {
                                  "types": [
                                    "locality",
                                    "political"
                                  ],
                                  "long_name": "Madrid",
                                  "short_name": "Madrid"
                                },
                                {
                                  "types": [
                                    "country",
                                    "political"
                                  ],
                                  "long_name": "Spain",
                                  "short_name": "ES"
                                },
                                {
                                  "types": [
                                    "postal_code"
                                  ],
                                  "long_name": "28822",
                                  "short_name": "28822"
                                }
                              ]
                            },
                            "address_type": "Avda",
                            "document_location": {
                              "latitude": 37.4222804,
                              "longitude": -122.0843428
                            },
                            "formatted_address": "Avda de Madrid 34, 28822 Madrid, Spain"
                          },
                          "front_image_camera_front_face_match_score": 95.5,
                          "back_image_camera_front_face_match_score": 93.2,
                          "document_selfie_face_matches": [
                            {
                              "session_id": "3f0c9a52-7b1e-4d68-a2c4-5e9d8b7f1a20",
                              "session_number": 1180,
                              "similarity_percentage": 97.4,
                              "vendor_data": "user_ref_001",
                              "vendor_user_id": null,
                              "biometric_template_id": null,
                              "verification_date": "2026-09-02T09:15:00Z",
                              "user_details": {
                                "full_name": "Jane Doe"
                              },
                              "match_image_url": "https://<media-host>/match_face.jpg",
                              "status": "Approved",
                              "is_blocklisted": false,
                              "is_allowlisted": false,
                              "api_service": null,
                              "source": "session"
                            }
                          ],
                          "front_image_quality_score": {
                            "focus_score": 85.3,
                            "brightness_score": 92.1,
                            "brightness_issue": "ok",
                            "is_document_fully_visible": true,
                            "resolution_score": 72.4,
                            "overall_score": 88.7
                          },
                          "back_image_quality_score": {
                            "focus_score": 79.1,
                            "brightness_score": 90.5,
                            "brightness_issue": "ok",
                            "is_document_fully_visible": true,
                            "resolution_score": 72.4,
                            "overall_score": 85.2
                          },
                          "extra_files": [
                            "https://<media-host>/extra_id_verification.jpg"
                          ],
                          "matches": [
                            {
                              "session_id": "7d4f1f60-9c2e-4b8a-8f3d-2a1b5c6d7e8f",
                              "session_number": 1234,
                              "vendor_data": "user_ref_001",
                              "verification_date": "2024-06-15T10:30:00Z",
                              "user_details": {
                                "name": "John Smith",
                                "document_type": "ID",
                                "document_number": "CLM148418"
                              },
                              "status": "Approved",
                              "is_blocklisted": false,
                              "api_service": null,
                              "front_image_url": "https://<media-host>/document_front.jpg"
                            },
                            {
                              "session_id": "b2c8e4d1-6a3f-4e7b-95c0-1d8f2a6b4c9e",
                              "session_number": 1235,
                              "vendor_data": null,
                              "verification_date": "2024-05-20T14:45:00Z",
                              "user_details": {
                                "name": "John Smith",
                                "document_type": "ID",
                                "document_number": "CLM148418"
                              },
                              "status": "Declined",
                              "is_blocklisted": true,
                              "api_service": "ID_VERIFICATION",
                              "front_image_url": "https://<media-host>/document_front_2.jpg"
                            }
                          ],
                          "warnings": [
                            {
                              "feature": "ID_VERIFICATION",
                              "risk": "QR_NOT_DETECTED",
                              "additional_data": null,
                              "log_type": "information",
                              "short_description": "QR not detected",
                              "long_description": "The system couldn't find or read the QR code on the document, which is necessary for document verification. This could be due to poor image quality or an unsupported document type.",
                              "node_id": "feature_ocr_1"
                            }
                          ],
                          "verification_method": "document",
                          "assurance": "documentary",
                          "wallet_provider": null,
                          "fallback_from": null,
                          "id_lookup": null,
                          "wallet_verification": null,
                          "document_liveness": {
                            "portrait_replace": {
                              "score": 96.46,
                              "front": 96.46,
                              "back": 98.2,
                              "decline_threshold": 35,
                              "review_threshold": 70,
                              "bucket": "approve"
                            },
                            "printed_copy": {
                              "score": 91.2,
                              "front": 91.2,
                              "back": 93.7,
                              "decline_threshold": 35,
                              "review_threshold": 77,
                              "bucket": "approve"
                            },
                            "screen_replay": {
                              "score": 99.9,
                              "front": 99.9,
                              "back": 99.5,
                              "decline_threshold": 30,
                              "review_threshold": 70,
                              "bucket": "approve"
                            }
                          }
                        },
                        {
                          "node_id": "feature_ocr_2",
                          "status": "Approved",
                          "issuing_state": "ZAF",
                          "issuing_state_name": "South Africa",
                          "first_name": "Thabo",
                          "last_name": "Mokoena",
                          "full_name": "Thabo Mokoena",
                          "date_of_birth": "1991-06-15",
                          "personal_number": "9106155043088",
                          "verification_method": "id_lookup",
                          "assurance": "data_match",
                          "wallet_provider": null,
                          "fallback_from": null,
                          "id_lookup": {
                            "source": "Department of Home Affairs",
                            "checked_at": "2026-09-04T09:12:44Z",
                            "attempts": 1,
                            "max_attempts": 2,
                            "outcome": "match",
                            "comparison": [
                              {
                                "field": "identification_number",
                                "label": "ID number",
                                "provided": "9106155043088",
                                "record": "9106155043088",
                                "result": "match"
                              },
                              {
                                "field": "full_name",
                                "label": "Full name",
                                "provided": "Thabo Mokoena",
                                "record": "Thabo Mokoena",
                                "result": "match"
                              },
                              {
                                "field": "date_of_birth",
                                "label": "Date of birth",
                                "provided": "1991-06-15",
                                "record": "1991-06-15",
                                "result": "match"
                              }
                            ],
                            "registry_portrait": "https://<media-host>/registry_portrait.jpg",
                            "face_match_score": 96.4,
                            "source_errors": []
                          },
                          "wallet_verification": null,
                          "warnings": []
                        },
                        {
                          "node_id": "feature_ocr_3",
                          "status": "Approved",
                          "issuing_state": "DNK",
                          "issuing_state_name": "Denmark",
                          "first_name": "Freja",
                          "last_name": "Nielsen",
                          "full_name": "Freja Nielsen",
                          "date_of_birth": "1988-03-02",
                          "verification_method": "wallet",
                          "assurance": "cryptographic",
                          "wallet_provider": "mitid",
                          "fallback_from": null,
                          "id_lookup": null,
                          "wallet_verification": {
                            "provider": "mitid",
                            "provider_name": "MitID",
                            "issuing_authority": "Danish Agency for Digital Government",
                            "issuing_country": "DNK",
                            "credential_type": "person_identification",
                            "level_of_assurance": "substantial",
                            "verified_at": "2026-09-04T09:12:44Z",
                            "signature_valid": true,
                            "attributes": {
                              "full_name": "Freja Nielsen",
                              "date_of_birth": "1988-03-02",
                              "cpr_alias": "b0f1c2d3-e4f5-4678-9abc-def012345678"
                            },
                            "portrait": null,
                            "face_match_score": null
                          },
                          "warnings": []
                        }
                      ],
                      "nfc_verifications": [
                        {
                          "node_id": "feature_nfc_1",
                          "status": "In Review",
                          "is_nfc_skipped": false,
                          "skip_reason": null,
                          "chip_protocol": "icao",
                          "jpki": null,
                          "portrait_image": "https://<media-host>/portrait.jpg",
                          "signature_image": "https://<media-host>/signature.jpg",
                          "chip_data": {
                            "document_type": "ID",
                            "issuing_country": "ESP",
                            "document_number": "123456789",
                            "expiration_date": "2030-01-01",
                            "first_name": "John",
                            "last_name": "Smith",
                            "birth_date": "1990-05-15",
                            "gender": "M",
                            "nationality": "ESP",
                            "address": "CALLE MAYOR 123 4B, MADRID, MADRID",
                            "place_of_birth": "MADRID, MADRID"
                          },
                          "authenticity": {
                            "sod_integrity": true,
                            "dg_integrity": true
                          },
                          "certificate_summary": {
                            "issuer": "Common Name: CSCA SPAIN, Serial Number: 3, Organization: DIRECCION GENERAL DE LA POLICIA, Country: ES",
                            "subject": "Common Name: DS n-eID SPAIN 2, Organizational Unit: PASSPORT, Organization: DIRECCION GENERAL DE LA POLICIA, Country: ES",
                            "serial_number": "118120836164494130086420187336801405660",
                            "not_valid_after": "2031-02-18 10:21:11",
                            "not_valid_before": "2020-11-18 10:21:11"
                          },
                          "warnings": [
                            {
                              "feature": "NFC",
                              "risk": "DATA_INCONSISTENT",
                              "additional_data": null,
                              "log_type": "warning",
                              "short_description": "OCR and NFC mrz code extracted are not the same",
                              "long_description": "The Optical Character Recognition (OCR) data and the NFC chip data don't match, indicating potential document tampering or data inconsistency.",
                              "node_id": "feature_nfc_1"
                            }
                          ]
                        }
                      ],
                      "liveness_checks": [
                        {
                          "node_id": "feature_liveness_1",
                          "status": "Approved",
                          "method": "ACTIVE_3D",
                          "score": 89.92,
                          "reference_image": "https://<media-host>/reference.jpg",
                          "video_url": "https://<media-host>/video.mp4",
                          "age_estimation": 24.3,
                          "matches": [
                            {
                              "session_id": "7d4f1f60-9c2e-4b8a-8f3d-2a1b5c6d7e8f",
                              "session_number": 1234,
                              "vendor_data": "user_ref_001",
                              "verification_date": "2024-06-15T10:30:00Z",
                              "user_details": {
                                "full_name": "John Smith",
                                "document_type": "ID",
                                "document_number": "CLM148418"
                              },
                              "status": "Approved",
                              "is_blocklisted": false,
                              "is_allowlisted": false,
                              "api_service": null,
                              "source": "session",
                              "match_image_url": "https://<media-host>/face_match.jpg",
                              "similarity_percentage": 98.5
                            },
                            {
                              "session_id": "3e9a7c21-5b48-4f0e-9c6a-8d2f4b1e0a35",
                              "session_number": 1100,
                              "vendor_data": "customer_xyz",
                              "verification_date": "2024-04-10T09:15:00Z",
                              "user_details": {
                                "full_name": "John Smith",
                                "document_type": "P",
                                "document_number": "DZ8375806"
                              },
                              "status": "Approved",
                              "is_blocklisted": false,
                              "is_allowlisted": false,
                              "api_service": "PASSIVE_LIVENESS",
                              "source": "session",
                              "match_image_url": "https://<media-host>/face_match_2.jpg",
                              "similarity_percentage": 95.2
                            }
                          ],
                          "warnings": [
                            {
                              "feature": "LIVENESS",
                              "risk": "LOW_LIVENESS_SCORE",
                              "additional_data": null,
                              "log_type": "information",
                              "short_description": "Low liveness score",
                              "long_description": "The liveness check resulted in a low score, indicating potential use of non-live facial representations or poor-quality biometric data.",
                              "node_id": "feature_liveness_1"
                            }
                          ],
                          "face_quality": null,
                          "face_luminance": null
                        }
                      ],
                      "face_matches": [
                        {
                          "node_id": "feature_face_match_1",
                          "status": "In Review",
                          "score": 65.43,
                          "source_image_session_id": null,
                          "source_image": "https://<media-host>/source-image.jpg",
                          "target_image": "https://<media-host>/target-image.jpg",
                          "warnings": [
                            {
                              "feature": "FACEMATCH",
                              "risk": "LOW_FACE_MATCH_SIMILARITY",
                              "additional_data": null,
                              "log_type": "warning",
                              "short_description": "Low face match similarity",
                              "long_description": "The facial features of the provided image don't closely match the reference image, suggesting a potential identity mismatch.",
                              "node_id": "feature_face_match_1"
                            }
                          ]
                        }
                      ],
                      "phone_verifications": [
                        {
                          "node_id": "feature_phone_1",
                          "status": "Approved",
                          "phone_number_prefix": "+34",
                          "phone_number": "600600600",
                          "full_number": "+34600600600",
                          "country_code": "ES",
                          "country_name": "Spain",
                          "carrier": {
                            "name": "Orange",
                            "type": "mobile"
                          },
                          "is_disposable": false,
                          "is_virtual": false,
                          "verification_method": "sms",
                          "verification_attempts": 1,
                          "verified_at": "2024-07-28T06:47:35.654321Z",
                          "lifecycle": [
                            {
                              "type": "PHONE_VERIFICATION_MESSAGE_SENT",
                              "timestamp": "2025-08-24T09:12:39.580554+00:00",
                              "details": {
                                "status": "Success",
                                "reason": null,
                                "channel": "sms",
                                "actual_channel": "sms"
                              },
                              "fee": 0.1
                            },
                            {
                              "type": "VALID_CODE_ENTERED",
                              "timestamp": "2025-08-24T09:12:39.662157+00:00",
                              "details": {
                                "code_tried": "123456",
                                "status": "Approved"
                              },
                              "fee": 0
                            },
                            {
                              "type": "PHONE_VERIFICATION_APPROVED",
                              "timestamp": "2025-08-24T09:12:39.684292+00:00",
                              "details": null,
                              "fee": 0
                            }
                          ],
                          "warnings": [],
                          "matches": [
                            {
                              "session_id": null,
                              "session_number": null,
                              "vendor_data": null,
                              "verification_date": null,
                              "phone_number": "+34600000000",
                              "status": null,
                              "is_blocklisted": true,
                              "api_service": null,
                              "source": "list_entry"
                            }
                          ]
                        }
                      ],
                      "email_verifications": [
                        {
                          "node_id": "feature_email_1",
                          "status": "Approved",
                          "email": "test@example.com",
                          "is_breached": true,
                          "breaches": [
                            {
                              "name": "TAPAirPortugal",
                              "domain": "flytap.com",
                              "logo_path": "https://logos.example.com/TAPAirPortugal.png",
                              "breach_date": "2022-08-25",
                              "description": "In August 2022, the Portuguese airline <a href=\"https://www.bleepingcomputer.com/news/security/ragnar-locker-ransomware-claims-attack-on-portugals-flag-airline/\" target=\"_blank\" rel=\"noopener\">TAP Air Portugal was the target of a ransomware attack perpetrated by the Ragnar Locker gang</a> who later leaked the compromised data via a public dark web site. Over 5M unique email addresses were exposed alongside other personal data including names, genders, DoBs, phone numbers and physical addresses.",
                              "is_verified": true,
                              "data_classes": [
                                "dates_of_birth",
                                "email_addresses",
                                "genders",
                                "names",
                                "nationalities",
                                "phone_numbers",
                                "physical_addresses",
                                "salutations",
                                "spoken_languages"
                              ],
                              "breach_emails_count": 6083479
                            }
                          ],
                          "is_disposable": false,
                          "is_undeliverable": false,
                          "verification_attempts": 1,
                          "verified_at": "2025-09-15T17:36:19.963451Z",
                          "warnings": [
                            {
                              "feature": "EMAIL",
                              "risk": "BREACHED_EMAIL_DETECTED",
                              "additional_data": null,
                              "log_type": "information",
                              "short_description": "Breached email detected",
                              "long_description": "This email address was found in one or more known data breaches.",
                              "node_id": "feature_email_1"
                            }
                          ],
                          "lifecycle": [
                            {
                              "type": "EMAIL_VERIFICATION_MESSAGE_SENT",
                              "timestamp": "2025-09-15T17:36:19.792684+00:00",
                              "details": {
                                "status": "Success",
                                "reason": null
                              },
                              "fee": 0.02
                            },
                            {
                              "type": "VALID_CODE_ENTERED",
                              "timestamp": "2025-09-15T17:36:19.963427+00:00",
                              "details": {
                                "code_tried": "123456",
                                "status": "Approved"
                              },
                              "fee": 0
                            },
                            {
                              "type": "EMAIL_VERIFICATION_DECLINED",
                              "timestamp": "2025-09-15T17:36:20.081471+00:00",
                              "details": {
                                "reason": "BREACHED_EMAIL_DETECTED"
                              },
                              "fee": 0
                            }
                          ],
                          "matches": [
                            {
                              "session_id": null,
                              "session_number": null,
                              "vendor_data": null,
                              "verification_date": null,
                              "email": "test@example.com",
                              "status": null,
                              "is_blocklisted": true,
                              "api_service": null,
                              "source": "list_entry"
                            }
                          ]
                        }
                      ],
                      "poa_verifications": [
                        {
                          "node_id": "feature_poa_1",
                          "status": "Declined",
                          "document_file": "https://<media-host>/poa_document.pdf",
                          "issuing_state": "AR",
                          "document_type": "UTILITY_BILL",
                          "document_subtype": null,
                          "document_language": "es",
                          "document_metadata": {
                            "file_size": 1000,
                            "content_type": "application/pdf",
                            "creation_date": "2021-01-01",
                            "modified_date": "2021-01-01",
                            "overlay_manipulation": null,
                            "creator": null,
                            "producer": "PDF Generator",
                            "software": null,
                            "encryption": null,
                            "is_signed": false,
                            "is_tampered": false,
                            "signature_info": null,
                            "exif_original_date": null,
                            "exif_digitized_date": null,
                            "processed_by_known_editor": false,
                            "has_different_creation_mod_date": true
                          },
                          "issuer": "Aguas del Norte",
                          "issue_date": "2021-02-01",
                          "expiration_date": null,
                          "poa_address": "AVDA. MONSEÑOR TAVELLA N° 3396, SALTA",
                          "poa_formatted_address": "Av. Monseñor Tavella 3396, A4400 Salta, Argentina",
                          "poa_parsed_address": {
                            "address_type": "Avenida",
                            "street_1": "Avenida Monseñor Tavella 3396",
                            "street_2": null,
                            "city": "Salta",
                            "region": "Salta",
                            "country": "AR",
                            "postal_code": "A4400",
                            "document_location": {
                              "latitude": -24.8208664,
                              "longitude": -65.4131
                            }
                          },
                          "name_on_document": "Fernando De Lima",
                          "name_match_score_expected_details": null,
                          "name_match_score_id_verification": 38.5,
                          "expected_details_address": null,
                          "expected_details_formatted_address": null,
                          "expected_details_parsed_address": {},
                          "extra_fields": {
                            "bank_account_number": "1234567890",
                            "bank_iban": null,
                            "bank_sort_code": null,
                            "bank_routing_number": null,
                            "bank_swift_bic": null,
                            "bank_branch_name": null,
                            "bank_branch_address": null,
                            "document_phone_number": "+5491112345678",
                            "additional_names": []
                          },
                          "extra_files": [
                            "https://<media-host>/extra_poa.pdf"
                          ],
                          "detected_codes": [
                            {
                              "type": "QR_CODE",
                              "page_number": 1,
                              "position": [
                                [
                                  820,
                                  1120
                                ],
                                [
                                  1002,
                                  1120
                                ],
                                [
                                  1002,
                                  1302
                                ],
                                [
                                  820,
                                  1302
                                ]
                              ],
                              "x": 820,
                              "y": 1120,
                              "width": 182,
                              "height": 182,
                              "page_width": 1190,
                              "page_height": 1684,
                              "raw_payload": "aHR0cHM6Ly9hZ3Vhc2RlbG5vcnRlLmNvbS9mYWN0dXJhLzk5ODgxMQ==",
                              "parsed_payload": "https://aguasdelnorte.com/factura/998811"
                            },
                            {
                              "type": "CODE_128",
                              "page_number": 1,
                              "position": [
                                [
                                  112,
                                  1480
                                ],
                                [
                                  560,
                                  1480
                                ],
                                [
                                  560,
                                  1540
                                ],
                                [
                                  112,
                                  1540
                                ]
                              ],
                              "x": 112,
                              "y": 1480,
                              "width": 448,
                              "height": 60,
                              "page_width": 1190,
                              "page_height": 1684,
                              "raw_payload": "MDA5OTg4MTEwMDA0Mg==",
                              "parsed_payload": "0099881100042"
                            }
                          ],
                          "warnings": []
                        }
                      ],
                      "document_ai_documents": [
                        {
                          "status": "Approved",
                          "node_id": "feature_document_ai_1",
                          "items": [
                            {
                              "uuid": "c1a2b3c4-d5e6-7f80-9a1b-2c3d4e5f6071",
                              "node_id": "feature_document_ai_1",
                              "document_key": "proof_of_funds",
                              "original_filename": "bank_statement.pdf",
                              "file_size": 184320,
                              "file_url": "https://<media-host>/document_ai/proof_of_funds.pdf",
                              "status": "Approved",
                              "extracted_data": {
                                "account_holder": "John Doe",
                                "balance": 15230.55,
                                "currency": "EUR",
                                "statement_date": "2026-05-31"
                              },
                              "detected_codes": [
                                {
                                  "type": "QR_CODE",
                                  "page_number": 2,
                                  "position": [
                                    [
                                      124,
                                      86
                                    ],
                                    [
                                      306,
                                      86
                                    ],
                                    [
                                      306,
                                      268
                                    ],
                                    [
                                      124,
                                      268
                                    ]
                                  ],
                                  "x": 124,
                                  "y": 86,
                                  "width": 182,
                                  "height": 182,
                                  "page_width": 1190,
                                  "page_height": 1684,
                                  "raw_payload": "SU5WLTIwMjYtMDA0Mg==",
                                  "parsed_payload": "INV-2026-0042"
                                }
                              ],
                              "fields": [
                                {
                                  "key": "account_holder",
                                  "name": "Account holder",
                                  "instruction": "Extract the full name of the account holder.",
                                  "type": "text",
                                  "required": true
                                },
                                {
                                  "key": "balance",
                                  "name": "Closing balance",
                                  "instruction": "Extract the closing balance amount.",
                                  "type": "number",
                                  "required": true
                                }
                              ],
                              "document_metadata": {
                                "is_tampered": false
                              },
                              "cross_check_result": null,
                              "created_at": "2026-06-01T12:34:56Z"
                            }
                          ],
                          "warnings": []
                        }
                      ],
                      "questionnaire_responses": [
                        {
                          "node_id": "feature_questionnaire_1",
                          "questionnaire_id": "9f7485e0-b00b-4d56-9d3e-7859b68d1213",
                          "title": "Source of Funds",
                          "description": "Reply to this questionnaire to help us understand the source of funds.",
                          "languages": [
                            "en"
                          ],
                          "default_language": "en",
                          "is_active": true,
                          "is_simple_questionnaire": true,
                          "questionnaire_group_id": "2b6a9d40-13a8-4b1e-9a6c-3f1d2e4b5a60",
                          "version": 1,
                          "published_at": "2025-11-02T09:14:55.000000Z",
                          "sections": [
                            {
                              "title": null,
                              "description": null,
                              "items": [
                                {
                                  "uuid": "618636d9-7d5c-41ce-b8d0-1ab2a4be20db",
                                  "value": "question_1",
                                  "element_type": "DROPDOWN",
                                  "is_required": true,
                                  "title": "What is your primary source of funds?",
                                  "description": null,
                                  "placeholder": null,
                                  "choices": [
                                    {
                                      "label": "Salary",
                                      "value": "salary"
                                    },
                                    {
                                      "label": "Business Income",
                                      "value": "business_income"
                                    },
                                    {
                                      "label": "Savings",
                                      "value": "savings"
                                    },
                                    {
                                      "label": "Investments",
                                      "value": "investments"
                                    },
                                    {
                                      "label": "Sale of Asset",
                                      "value": "sale_of_asset"
                                    },
                                    {
                                      "label": "Inheritance/Gift",
                                      "value": "inheritance_gift"
                                    },
                                    {
                                      "label": "Pension",
                                      "value": "pension"
                                    },
                                    {
                                      "label": "Crypto Proceeds",
                                      "value": "crypto_proceeds"
                                    },
                                    {
                                      "label": "Other",
                                      "value": "other",
                                      "requires_text_input": true
                                    }
                                  ],
                                  "max_files": 1,
                                  "answer": {
                                    "value": "salary"
                                  },
                                  "required_if": null,
                                  "repeatable_config": null
                                },
                                {
                                  "uuid": "2d16b527-72be-42e0-8e96-b164b818386c",
                                  "value": "question_2",
                                  "element_type": "LONG_TEXT",
                                  "is_required": true,
                                  "title": "Provide details of the primary source.",
                                  "description": null,
                                  "placeholder": null,
                                  "choices": null,
                                  "max_files": 1,
                                  "answer": {
                                    "value": "Test answer"
                                  },
                                  "required_if": null,
                                  "repeatable_config": null
                                },
                                {
                                  "uuid": "a9239b7c-fbfb-4ea7-b7e4-c835cd4016e0",
                                  "value": "question_3",
                                  "element_type": "DROPDOWN",
                                  "is_required": true,
                                  "title": "What is your annual income range (pre-tax)?",
                                  "description": null,
                                  "placeholder": null,
                                  "choices": [
                                    {
                                      "label": "Less than $25,000",
                                      "value": "<25k"
                                    },
                                    {
                                      "label": "$25,000 - $50,000",
                                      "value": "25k-50k"
                                    },
                                    {
                                      "label": "$50,001 - $100,000",
                                      "value": "50k-100k"
                                    },
                                    {
                                      "label": "$100,001 - $250,000",
                                      "value": "100k-250k"
                                    },
                                    {
                                      "label": "More than $250,000",
                                      "value": ">250k"
                                    }
                                  ],
                                  "max_files": 1,
                                  "answer": {
                                    "value": "<25k"
                                  },
                                  "required_if": null,
                                  "repeatable_config": null
                                },
                                {
                                  "uuid": "93dede62-6d0c-4a7f-934d-42175eb94011",
                                  "value": "question_4",
                                  "element_type": "DROPDOWN",
                                  "is_required": true,
                                  "title": "What is your approximate net worth (range)?",
                                  "description": null,
                                  "placeholder": null,
                                  "choices": [
                                    {
                                      "label": "Less than $50,000",
                                      "value": "<50k"
                                    },
                                    {
                                      "label": "$50,000 - $250,000",
                                      "value": "50k-250k"
                                    },
                                    {
                                      "label": "$250,001 - $1,000,000",
                                      "value": "250k-1m"
                                    },
                                    {
                                      "label": "$1,000,001 - $5,000,000",
                                      "value": "1m-5m"
                                    },
                                    {
                                      "label": "More than $5,000,000",
                                      "value": ">5m"
                                    }
                                  ],
                                  "max_files": 1,
                                  "answer": {
                                    "value": "<50k"
                                  },
                                  "required_if": null,
                                  "repeatable_config": null
                                },
                                {
                                  "uuid": "2af60d6f-6961-4692-9ee7-24b3033610a6",
                                  "value": "question_5",
                                  "element_type": "LONG_TEXT",
                                  "is_required": true,
                                  "title": "For your initial deposit/funding, indicate the exact source and amount.",
                                  "description": null,
                                  "placeholder": null,
                                  "choices": null,
                                  "max_files": 1,
                                  "answer": {
                                    "value": "Test answer"
                                  },
                                  "required_if": null,
                                  "repeatable_config": null
                                },
                                {
                                  "uuid": "0ad9d1aa-736f-46cf-947b-9e1241b53e40",
                                  "value": "question_6",
                                  "element_type": "LONG_TEXT",
                                  "is_required": true,
                                  "title": "Breakdown of sources by percentage.",
                                  "description": null,
                                  "placeholder": null,
                                  "choices": null,
                                  "max_files": 1,
                                  "answer": {
                                    "value": "Test answer"
                                  },
                                  "required_if": null,
                                  "repeatable_config": null
                                },
                                {
                                  "uuid": "1bf8a2a3-14ee-48a8-bb3d-175481aae4aa",
                                  "value": "question_7",
                                  "element_type": "SINGLE_CHOICE",
                                  "is_required": true,
                                  "title": "Will any funds originate from third parties? If yes, please provide details.",
                                  "description": null,
                                  "placeholder": null,
                                  "choices": [
                                    {
                                      "label": "Yes",
                                      "value": "yes",
                                      "requires_text_input": true
                                    },
                                    {
                                      "label": "No",
                                      "value": "no"
                                    }
                                  ],
                                  "max_files": 1,
                                  "answer": {
                                    "text": "Additional details",
                                    "value": "yes"
                                  },
                                  "required_if": null,
                                  "repeatable_config": null
                                },
                                {
                                  "uuid": "e18d4dd3-b7bf-4883-ba18-d6046adbe313",
                                  "value": "question_8",
                                  "element_type": "SINGLE_CHOICE",
                                  "is_required": true,
                                  "title": "Do you hold or plan to use virtual assets (e.g., crypto) to fund this account? If yes, please provide details.",
                                  "description": null,
                                  "placeholder": null,
                                  "choices": [
                                    {
                                      "label": "Yes",
                                      "value": "yes",
                                      "requires_text_input": true
                                    },
                                    {
                                      "label": "No",
                                      "value": "no"
                                    }
                                  ],
                                  "max_files": 1,
                                  "answer": {
                                    "text": "Additional details",
                                    "value": "yes"
                                  },
                                  "required_if": null,
                                  "repeatable_config": null
                                },
                                {
                                  "uuid": "a90a073d-e098-404c-bbce-5130d8b12a13",
                                  "value": "question_9",
                                  "element_type": "FILE_UPLOAD",
                                  "is_required": true,
                                  "title": "Upload a proof of funds document",
                                  "description": "You can upload your three (3) most recent bank statements, three (3) most recent payslips, your most recent tax return, proof of company ownership, trading exchange statement, sale of property, or proof of inheritance.",
                                  "placeholder": null,
                                  "choices": null,
                                  "max_files": 3,
                                  "answer": {
                                    "files": [
                                      "/media/ocr/",
                                      "/media/ocr/"
                                    ]
                                  },
                                  "required_if": null,
                                  "repeatable_config": null
                                },
                                {
                                  "uuid": "9503b486-7cb8-4c3b-a97d-4b64926a5a47",
                                  "value": "question_10",
                                  "element_type": "LONG_TEXT",
                                  "is_required": false,
                                  "title": "Would you like to add any details to help us expedite our review of the documents you submitted?",
                                  "description": null,
                                  "placeholder": null,
                                  "choices": null,
                                  "max_files": 1,
                                  "answer": {
                                    "value": "Test answer"
                                  },
                                  "required_if": null,
                                  "repeatable_config": null
                                }
                              ]
                            }
                          ],
                          "status": "Approved"
                        }
                      ],
                      "aml_screenings": [
                        {
                          "node_id": "feature_aml_1",
                          "status": "In Review",
                          "total_hits": 1,
                          "entity_type": "person",
                          "hits": [
                            {
                              "id": "hit_7c1e9a40b2d35f86e0a4c912",
                              "url": "https://news.example.org/articles/sample",
                              "match": false,
                              "score": 0.73,
                              "target": null,
                              "caption": "Javier Ejemplo Modelo",
                              "datasets": [
                                "PEP"
                              ],
                              "features": null,
                              "rca_name": "",
                              "last_seen": "2025-06-13T00:00:00",
                              "risk_view": {
                                "crimes": {
                                  "score": 0,
                                  "weightage": 20,
                                  "risk_level": "Low",
                                  "risk_scores": {}
                                },
                                "countries": {
                                  "score": 0,
                                  "weightage": 30,
                                  "risk_level": "Low",
                                  "risk_scores": {}
                                },
                                "categories": {
                                  "score": 100,
                                  "weightage": 50,
                                  "risk_level": "High",
                                  "risk_scores": {
                                    "PEP": 100
                                  }
                                },
                                "custom_list": {}
                              },
                              "first_seen": "2025-01-18T00:00:00",
                              "properties": {
                                "name": [
                                  "Javier Ejemplo Modelo"
                                ],
                                "alias": [
                                  "Javier Ejemplo Modelo",
                                  "David Azagra"
                                ],
                                "notes": [
                                  "Spanish orchestra conductor"
                                ],
                                "title": null,
                                "gender": [
                                  "male"
                                ],
                                "height": null,
                                "topics": null,
                                "weight": null,
                                "address": null,
                                "country": null,
                                "website": null,
                                "eyeColor": null,
                                "keywords": null,
                                "lastName": [
                                  "Ejemplo",
                                  "Modelo"
                                ],
                                "position": null,
                                "religion": null,
                                "birthDate": [
                                  "1974"
                                ],
                                "education": [
                                  "Tokyo Arts and Space (2012-2012)",
                                  "Saint Petersburg Conservatory (-2010)",
                                  "Comillas Pontifical University"
                                ],
                                "ethnicity": null,
                                "firstName": [
                                  "David"
                                ],
                                "hairColor": null,
                                "weakAlias": null,
                                "birthPlace": [
                                  "Madrid"
                                ],
                                "modifiedAt": null,
                                "wikidataId": null,
                                "citizenship": null,
                                "nationality": null
                              },
                              "match_score": 98,
                              "risk_score": 73,
                              "review_status": "Unreviewed",
                              "score_breakdown": {
                                "name_score": 95,
                                "name_weight": 60,
                                "name_weight_normalized": 70.59,
                                "name_contribution": 67.06,
                                "dob_score": 100,
                                "dob_weight": 25,
                                "dob_weight_normalized": 29.41,
                                "dob_contribution": 29.41,
                                "country_score": 0,
                                "country_weight": 15,
                                "country_weight_normalized": 0,
                                "country_contribution": 0,
                                "document_number_match_type": "NEUTRAL",
                                "document_number_effect": "No document number provided for screening",
                                "total_score": 98
                              },
                              "pep_matches": [
                                {
                                  "aliases": [
                                    "Javier Ejemplo Modelo",
                                    "David Azagra"
                                  ],
                                  "education": [
                                    "Tokyo Arts and Space (2012-2012)",
                                    "Saint Petersburg Conservatory (-2010)",
                                    "Comillas Pontifical University"
                                  ],
                                  "list_name": "Wikidata",
                                  "publisher": "Wikidata",
                                  "source_url": "https://news.example.org/articles/sample",
                                  "description": "Wikidata is the structured data project of the Wikipedia community, providing fact-based information edited by humans and machines",
                                  "matched_name": "Javier Ejemplo Modelo",
                                  "pep_position": "",
                                  "date_of_birth": "1974",
                                  "other_sources": [],
                                  "place_of_birth": "Madrid"
                                }
                              ],
                              "linked_entities": [
                                {
                                  "name": [
                                    "Antonio Ejemplo"
                                  ],
                                  "active": [],
                                  "status": [],
                                  "details": [],
                                  "relation": []
                                }
                              ],
                              "warning_matches": [],
                              "sanction_matches": [],
                              "adverse_media_details": {
                                "sentiment": "Moderately Negative",
                                "entity_type": "person",
                                "sentiment_score": -2,
                                "adverse_keywords": {
                                  "fraud": 3,
                                  "juicio": 1,
                                  "delitos": 2,
                                  "imputado": 1,
                                  "impunidad": 1,
                                  "corruption": 2,
                                  "favoritism": 2,
                                  "privilegio": 1,
                                  "corrupción": 1,
                                  "persecution": 2,
                                  "desconfianza": 1,
                                  "desprestigio": 1,
                                  "fraude de ley": 2,
                                  "manipulación": 1,
                                  "investigación": 3,
                                  "prevaricación": 8,
                                  "trato de favor": 1,
                                  "irregularidades": 2,
                                  "crisis de confianza": 1,
                                  "tráfico de influencias": 8
                                }
                              },
                              "adverse_media_matches": [
                                {
                                  "country": "spain",
                                  "summary": "Javier Ejemplo is implicated in legal violations related to favoritism and influence trafficking, leading to a negative portrayal in the article.",
                                  "headline": "La Diputación de Villaejemplo consolida la plaza a medida para el ex asesor de Moncloa amigo del \"hermanito\" de Ejemplo",
                                  "sentiment": "moderately negative",
                                  "thumbnail": "https://news.example.org/articles/sample",
                                  "source_url": "https://news.example.org/articles/sample",
                                  "author_name": null,
                                  "other_sources": [],
                                  "adverse_keywords": [
                                    "fraud",
                                    "prevaricación",
                                    "tráfico de influencias",
                                    "irregularidades",
                                    "imputado"
                                  ],
                                  "sentiment_score": -2,
                                  "publication_date": "2025-06-10T20:46:38"
                                },
                                {
                                  "country": "spain",
                                  "summary": "Javier Ejemplo is implicated in legal issues regarding favoritism and corruption, leading to a negative portrayal in the article.",
                                  "headline": "La Diputación de Villaejemplo consolida la plaza a medida para el ex asesor de Moncloa amigo del \"hermanito\" de Ejemplo",
                                  "sentiment": "moderately negative",
                                  "thumbnail": "https://news.example.org/articles/sample",
                                  "source_url": "https://news.example.org/articles/sample",
                                  "author_name": null,
                                  "other_sources": [],
                                  "adverse_keywords": [
                                    "fraud",
                                    "prevaricación",
                                    "tráfico de influencias",
                                    "irregularidades",
                                    "trato de favor"
                                  ],
                                  "sentiment_score": -2,
                                  "publication_date": "2025-06-10T20:46:38"
                                },
                                {
                                  "country": "spain",
                                  "summary": "Javier Ejemplo Modelo is mentioned in connection with Carlos Ficticio's corruption case, indicating his involvement in alleged influence peddling.",
                                  "headline": "España, paraíso del aforado",
                                  "sentiment": "moderately negative",
                                  "thumbnail": "https://news.example.org/articles/sample",
                                  "source_url": "https://news.example.org/articles/sample",
                                  "author_name": null,
                                  "other_sources": [],
                                  "adverse_keywords": [
                                    "prevaricación",
                                    "tráfico de influencias",
                                    "corrupción",
                                    "impunidad",
                                    "privilegio",
                                    "desconfianza",
                                    "manipulación",
                                    "fraude de ley"
                                  ],
                                  "sentiment_score": -2,
                                  "publication_date": "2025-06-10T05:05:34"
                                },
                                {
                                  "country": "spain",
                                  "summary": "Javier Ejemplo Modelo is implicated in the same investigation as Ficticio, which raises questions about his conduct and political ethics.",
                                  "headline": "Aforamientos: esa figura incómoda",
                                  "sentiment": "moderately negative",
                                  "thumbnail": "https://news.example.org/articles/sample",
                                  "source_url": "https://news.example.org/articles/sample",
                                  "author_name": null,
                                  "other_sources": [],
                                  "adverse_keywords": [
                                    "prevaricación",
                                    "tráfico de influencias",
                                    "investigación",
                                    "juicio",
                                    "fraude de ley",
                                    "desprestigio",
                                    "crisis de confianza",
                                    "delitos"
                                  ],
                                  "sentiment_score": -2,
                                  "publication_date": "2025-06-08T06:01:00"
                                },
                                {
                                  "country": "spain",
                                  "summary": "Javier Ejemplo is implicated in a legal investigation regarding irregularities in his hiring, which raises serious concerns about his conduct.",
                                  "headline": "La jueza del 'caso Javier Ejemplo' denuncia un «fraude de ley» en el aforamiento de Ficticio (Partido Ejemplo)",
                                  "sentiment": "moderately negative",
                                  "thumbnail": "https://news.example.org/articles/sample",
                                  "source_url": "https://news.example.org/articles/sample",
                                  "author_name": null,
                                  "other_sources": [],
                                  "adverse_keywords": [
                                    "fraud",
                                    "irregularities",
                                    "prevaricación",
                                    "tráfico de influencias"
                                  ],
                                  "sentiment_score": -2,
                                  "publication_date": "2025-06-09T10:19:10"
                                },
                                {
                                  "country": "spain",
                                  "summary": "Javier Ejemplo Modelo is mentioned in connection with legal allegations of corruption, contributing to a negative perception.",
                                  "headline": "'Caso aforamiento': la letrada mayor de la Asamblea certifica a la juez que Ficticio es diputado desde antes de prometer su cargo en el Pleno",
                                  "sentiment": "moderately negative",
                                  "thumbnail": "https://news.example.org/articles/sample",
                                  "source_url": "https://news.example.org/articles/sample",
                                  "author_name": null,
                                  "other_sources": [],
                                  "adverse_keywords": [
                                    "prevaricación",
                                    "tráfico de influencias"
                                  ],
                                  "sentiment_score": -2,
                                  "publication_date": "2025-06-09T08:08:30"
                                },
                                {
                                  "country": "spain",
                                  "summary": "Javier Ejemplo Modelo is implicated in the same investigation as Ficticio, raising concerns about political corruption and influence.",
                                  "headline": "Aforamientos: esa figura incómoda",
                                  "sentiment": "moderately negative",
                                  "thumbnail": "https://news.example.org/articles/sample",
                                  "source_url": "https://news.example.org/articles/sample",
                                  "author_name": null,
                                  "other_sources": [],
                                  "adverse_keywords": [
                                    "prevaricación",
                                    "tráfico de influencias",
                                    "investigación"
                                  ],
                                  "sentiment_score": -2,
                                  "publication_date": "2025-06-08T06:01:00"
                                },
                                {
                                  "country": "spain",
                                  "summary": "Javier Ejemplo Modelo is implicated in the same investigation as Ficticio, which raises concerns about political misconduct.",
                                  "headline": "Aforamientos: esa figura incómoda",
                                  "sentiment": "moderately negative",
                                  "thumbnail": "https://news.example.org/articles/sample",
                                  "source_url": "https://news.example.org/articles/sample",
                                  "author_name": null,
                                  "other_sources": [],
                                  "adverse_keywords": [
                                    "prevaricación",
                                    "tráfico de influencias",
                                    "investigación",
                                    "delitos"
                                  ],
                                  "sentiment_score": -2,
                                  "publication_date": "2025-06-08T06:00:59"
                                },
                                {
                                  "country": "spain",
                                  "summary": "Javier Ejemplo is implicated in a case of favoritism and corruption, which casts a negative light on his character and actions.",
                                  "headline": "'Caso Javier Ejemplo': las asociaciones judiciales salen en defensa de la juez Luisa Inventada ante las \"presiones externas\" que sufre",
                                  "sentiment": "moderately negative",
                                  "thumbnail": "https://news.example.org/articles/sample",
                                  "source_url": "https://news.example.org/articles/sample",
                                  "author_name": null,
                                  "other_sources": [],
                                  "adverse_keywords": [
                                    "favoritism",
                                    "corruption",
                                    "persecution"
                                  ],
                                  "sentiment_score": -2,
                                  "publication_date": "2025-06-06T10:08:15"
                                },
                                {
                                  "country": "spain",
                                  "summary": "Javier Ejemplo is implicated in a case of alleged favoritism and corruption, which casts a negative light on his character and actions.",
                                  "headline": "'Caso Javier Ejemplo': las asociaciones judiciales salen en defensa de la juez Luisa Inventada ante las \"presiones externas\" que sufre",
                                  "sentiment": "moderately negative",
                                  "thumbnail": "https://news.example.org/articles/sample",
                                  "source_url": "https://news.example.org/articles/sample",
                                  "author_name": null,
                                  "other_sources": [],
                                  "adverse_keywords": [
                                    "favoritism",
                                    "corruption",
                                    "persecution"
                                  ],
                                  "sentiment_score": -2,
                                  "publication_date": "2025-06-06T08:08:15"
                                }
                              ],
                              "additional_information": {}
                            }
                          ],
                          "score": 80,
                          "screened_data": {
                            "full_name": "Javier Ejemplo Modelo",
                            "nationality": "ES",
                            "date_of_birth": "1974-01-01",
                            "document_number": null
                          },
                          "is_ongoing_monitoring_enabled": true,
                          "next_ongoing_monitoring_bill_date": "2026-07-24",
                          "last_ongoing_screening_at": "2026-09-12T04:03:11Z",
                          "last_ongoing_screening_datasets_updated_at": "2026-09-11T06:00:00Z",
                          "warnings": [
                            {
                              "feature": "AML",
                              "risk": "POSSIBLE_MATCH_FOUND",
                              "additional_data": null,
                              "log_type": "warning",
                              "short_description": "Possible match found in AML screening",
                              "long_description": "The Anti-Money Laundering (AML) screening process identified potential matches with watchlists or high-risk databases, requiring further review.",
                              "node_id": "feature_aml_1"
                            }
                          ]
                        }
                      ],
                      "ip_analyses": [
                        {
                          "node_id": "feature_ip_1",
                          "status": "Approved",
                          "device_brand": "Apple",
                          "device_model": "iPhone",
                          "browser_family": "Mobile Safari",
                          "os_family": "iOS",
                          "platform": "mobile",
                          "device_fingerprint": "didit-fp-a1b2c3d4e5f6g7h8",
                          "ip_country": "Spain",
                          "ip_country_code": "ES",
                          "ip_state": "Barcelona",
                          "ip_city": "Barcelona",
                          "latitude": 41.4022,
                          "longitude": 2.1407,
                          "ip_address": "83.50.226.71",
                          "isp": null,
                          "organization": null,
                          "is_vpn_or_tor": false,
                          "is_data_center": false,
                          "time_zone": "Europe/Madrid",
                          "time_zone_offset": "+0100",
                          "ip": {
                            "location": {
                              "latitude": 40.2206327,
                              "longitude": 1.5770097
                            },
                            "distance_from_id_document": 23.4,
                            "distance_from_poa_document": 12.3
                          },
                          "id_document": {
                            "location": {
                              "latitude": 41.2706327,
                              "longitude": 1.9770097
                            },
                            "distance_from_ip": 23.4,
                            "distance_from_poa_document": 18.7
                          },
                          "poa_document": {
                            "location": {
                              "latitude": 41.2706327,
                              "longitude": 1.9770097
                            },
                            "distance_from_ip": 12.3,
                            "distance_from_id_document": 18.7
                          },
                          "warnings": [],
                          "matches": [
                            {
                              "session_id": "99999999-8888-7777-6666-555555555555",
                              "session_number": 41205,
                              "vendor_data": "22222222-2222-2222-2222-222222222222",
                              "verification_date": "2024-07-20T10:15:30Z",
                              "match_type": "ip_address",
                              "match_source": "ip_address",
                              "matched_value": "83.50.226.71",
                              "status": "Approved",
                              "is_blocklisted": false,
                              "api_service": null,
                              "source": "session",
                              "device_info": {
                                "device_brand": "Apple",
                                "device_model": "iPhone",
                                "browser_family": "Mobile Safari",
                                "os_family": "iOS",
                                "platform": "mobile",
                                "device_fingerprint": "didit-fp-f9e8d7c6b5a40312"
                              },
                              "location_info": {
                                "ip_address": "83.50.226.71",
                                "ip_country": "Spain",
                                "ip_country_code": "ES",
                                "ip_state": "Barcelona",
                                "ip_city": "Barcelona",
                                "is_vpn_or_tor": false,
                                "is_data_center": false
                              },
                              "confidence": 0.0,
                              "match_mode": "co_occurrence"
                            },
                            {
                              "session_id": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee",
                              "session_number": 42830,
                              "vendor_data": "33333333-3333-3333-3333-333333333333",
                              "verification_date": "2024-06-30T18:22:05Z",
                              "match_type": "device_fingerprint",
                              "match_source": "recovered_high",
                              "matched_value": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
                              "status": "Declined",
                              "is_blocklisted": false,
                              "api_service": null,
                              "source": "session",
                              "device_info": {
                                "device_brand": "Samsung",
                                "device_model": "SM-G991B",
                                "browser_family": "Chrome Mobile",
                                "os_family": "Android",
                                "platform": "mobile",
                                "device_fingerprint": null
                              },
                              "location_info": {
                                "ip_address": "83.50.231.18",
                                "ip_country": "Spain",
                                "ip_country_code": "ES",
                                "ip_state": "Madrid",
                                "ip_city": "Madrid",
                                "is_vpn_or_tor": false,
                                "is_data_center": false
                              },
                              "confidence": 1.0,
                              "match_mode": "deterministic",
                              "recovery_similarity": 0.9874,
                              "tls_ja4_corroborated": true,
                              "recovery_gate_reason": "hardware_root_match"
                            }
                          ]
                        }
                      ],
                      "database_validations": [
                        {
                          "node_id": "feature_db_validation_1",
                          "issuing_state": "BRA",
                          "validation_type": "one_by_one",
                          "screened_data": {
                            "last_name": "De Lima",
                            "first_name": "Fernando",
                            "tax_number": "01234567890",
                            "date_of_birth": "1980-01-01",
                            "document_type": "ID",
                            "expiration_date": "2030-01-01"
                          },
                          "validations": [
                            {
                              "service_id": "bra_cpf",
                              "service_name": "Brazil - CPF status check",
                              "outcome_code": "MATCH",
                              "validation": {
                                "full_name": "full_match",
                                "date_of_birth": "full_match",
                                "identification_number": "full_match"
                              },
                              "source_data": {
                                "identification_number": "01234567890",
                                "first_name": "FERNANDO",
                                "last_name": "DE LIMA",
                                "date_of_birth": "1980-01-01",
                                "gender": "M",
                                "nationality": "BRA"
                              }
                            }
                          ],
                          "match_type": "full_match",
                          "status": "Approved",
                          "warnings": []
                        }
                      ],
                      "reviews": [
                        {
                          "user": "compliance@example.com",
                          "new_status": "Declined",
                          "comment": "Possible match found in AML screening",
                          "created_at": "2024-07-18T13:29:00.366811Z"
                        }
                      ],
                      "created_at": "2024-07-24T08:54:25.443172Z",
                      "expires_at": "2025-07-24T08:54:25.443172Z",
                      "biometric_consent": {
                        "required": false,
                        "trigger": null,
                        "status": "not_required",
                        "given_at": null,
                        "declined_at": null,
                        "text_version": null,
                        "text_hash": null,
                        "locale": null,
                        "policy_url": null,
                        "step": null,
                        "node_id": null,
                        "ip_address": null,
                        "ip_country_code": null,
                        "ip_state": null,
                        "ip_city": null,
                        "user_agent": null,
                        "detected_ip_address": "83.50.226.71",
                        "detected_country_code": "ES",
                        "detected_state": "ES-B",
                        "detected_city": "Barcelona",
                        "declared_state": null,
                        "document_state": null,
                        "jurisdictions": [],
                        "retention_months": null,
                        "reason": null,
                        "decline_reason": null,
                        "face_data_deleted_at": null
                      }
                    }
                  },
                  "BusinessExample": {
                    "summary": "Contoh sesi bisnis (KYB)",
                    "description": "Keputusan `session_kind = \"business\"`: sesi KYB menggantikan array fitur KYC dengan `registry_checks`, `document_verifications`, dan `key_people_checks`, dengan tetap menyertakan `aml_screenings`, `phone_verifications`, `email_verifications`, `questionnaire_responses`, `ip_analyses`, `reviews`, serta pembungkus sesi.",
                    "value": {
                      "session_id": "66666666-7777-8888-9999-000000000000",
                      "session_kind": "business",
                      "session_number": 31415,
                      "session_url": "https://verify.didit.me/session/business123",
                      "status": "In Review",
                      "environment": "live",
                      "workflow_id": "abababab-cdcd-efef-0101-232323232323",
                      "features": [
                        "KYB_REGISTRY",
                        "KYB_DOCUMENTS",
                        "KYB_KEY_PEOPLE"
                      ],
                      "vendor_data": "merchant-001234",
                      "metadata": null,
                      "callback": "https://example.com/verification/callback",
                      "registry_checks": [
                        {
                          "status": "Approved",
                          "node_id": "feature_kyb_registry_1",
                          "data_resolved": true,
                          "company": {
                            "uuid": "dddd4444-eeee-5555-ffff-666677778888",
                            "node_id": "feature_kyb_registry_1",
                            "status": "Approved",
                            "registry_status": "active",
                            "data_resolved": true,
                            "company_name": "ACME HOLDINGS LTD",
                            "registration_number": "12345678",
                            "country_code": "GB",
                            "region": null,
                            "company_type": "Private Limited Company",
                            "incorporation_date": "2015-03-12",
                            "registered_address": "1 Example Street, London, EC1A 1AA",
                            "tax_number": null,
                            "risk_level": null,
                            "verification_status": "verified",
                            "is_from_registry": true,
                            "fetch_status": "resolved",
                            "alternative_names": null,
                            "nature_of_business": "62012 - Business and domestic software development",
                            "registered_capital": "100 GBP",
                            "registered_capital_amount": "100.00",
                            "registered_capital_currency": "GBP",
                            "website": null,
                            "email": null,
                            "phone": null,
                            "legal_entity_identifier": null,
                            "location_of_registration": "England and Wales",
                            "financial_summary": null,
                            "officers": [
                              {
                                "uuid": "aaaa1111-bbbb-2222-cccc-333344445555",
                                "name": "Jane Smith",
                                "designation": "Director",
                                "role": "director",
                                "nationality": "British",
                                "is_active": true,
                                "kyc_status": "Approved",
                                "kyc_session_url": "https://verify.didit.me/session/abc123def456"
                              }
                            ],
                            "beneficial_owners": [
                              {
                                "uuid": "bbbb2222-cccc-3333-dddd-444455556666",
                                "name": "John Doe",
                                "first_name": "John",
                                "last_name": "Doe",
                                "entity_type": "person",
                                "roles": [
                                  "ubo",
                                  "shareholder"
                                ],
                                "ownership_min_shares": "50",
                                "ownership_max_shares": "75",
                                "is_active": true,
                                "kyc_status": "Pending",
                                "kyc_session_url": "https://verify.didit.me/session/def456ghi789",
                                "effective_ownership_percent": 75.0
                              }
                            ],
                            "addresses": [
                              {
                                "type": "registered",
                                "address": "1 Example Street, London, EC1A 1AA",
                                "country": "GB"
                              }
                            ],
                            "industries": [
                              {
                                "code": "62012",
                                "description": "Business and domestic software development"
                              }
                            ],
                            "accounts": null,
                            "registry_data": {},
                            "user_provided_data": {
                              "company_name": "ACME HOLDINGS",
                              "registration_number": "12345678"
                            },
                            "confirmed_by_user_at": "2026-06-10T12:01:30.000000Z",
                            "last_console_edit_at": null,
                            "is_editable": false
                          },
                          "ownership_structure": {
                            "shareholders": [
                              {
                                "name": "John Doe",
                                "first_name": "John",
                                "last_name": "Doe",
                                "date_of_birth": null,
                                "country_of_birth": null,
                                "company_name": null,
                                "registration_number": null,
                                "entity_type": "person",
                                "nationality": null,
                                "designation": null,
                                "roles": [
                                  "shareholder"
                                ],
                                "ownership_min_shares": "75",
                                "ownership_max_shares": "75",
                                "voting_min_shares": null,
                                "voting_max_shares": null,
                                "appointment_date": null,
                                "is_active": true,
                                "shareholding": {
                                  "share_class": "ORDINARY",
                                  "number_of_shares": 750.0,
                                  "currency": "GBP",
                                  "nominal_value": 1.0,
                                  "total_value": null,
                                  "percentage": 75.0
                                }
                              }
                            ],
                            "beneficial_owners": []
                          },
                          "warnings": []
                        }
                      ],
                      "aml_screenings": null,
                      "document_verifications": [
                        {
                          "status": "In Review",
                          "node_id": "feature_kyb_documents_1",
                          "items": [
                            {
                              "uuid": "eeee5555-ffff-6666-0000-777788889999",
                              "document_type": "LEGAL_PRESENCE",
                              "document_subtype": "CERTIFICATE_OF_INCORPORATION",
                              "document_group": "LEGAL_PRESENCE",
                              "file_url": "https://<media-host>/kyb/certificate-of-incorporation.pdf",
                              "original_filename": "certificate_of_incorporation.pdf",
                              "file_size": 482133,
                              "status": "Approved",
                              "created_at": "2026-06-10T12:03:11.000000Z",
                              "cross_check_result": {
                                "critical": {
                                  "company_name": {
                                    "document": "ACME HOLDINGS LTD",
                                    "registry": "ACME HOLDINGS LTD",
                                    "score": 1.0,
                                    "match": true
                                  },
                                  "registration_number": {
                                    "document": "12345678",
                                    "registry": "12345678",
                                    "match": true
                                  }
                                },
                                "non_critical": {},
                                "people": {}
                              },
                              "document_metadata": {
                                "file_size": 482133,
                                "content_type": "application/pdf",
                                "creation_date": "2015-03-12T09:00:00",
                                "modified_date": "2015-03-12T09:00:00",
                                "creator": null,
                                "producer": null,
                                "software": null,
                                "encryption": null,
                                "is_signed": true,
                                "is_tampered": false,
                                "signature_info": null,
                                "exif_original_date": null,
                                "exif_digitized_date": null,
                                "processed_by_known_editor": false,
                                "has_different_creation_mod_date": false,
                                "overlay_manipulation": null
                              },
                              "description": null,
                              "is_requested": false,
                              "ocr_data": {
                                "company_name": "ACME HOLDINGS LTD",
                                "registration_number": "12345678",
                                "incorporation_date": "2015-03-12"
                              },
                              "is_console_upload": false,
                              "is_confirmed": true
                            },
                            {
                              "uuid": "ffff6666-0000-7777-1111-888899990000",
                              "document_type": "OWNERSHIP_STRUCTURE",
                              "document_subtype": null,
                              "document_group": "OWNERSHIP_STRUCTURE",
                              "file_url": null,
                              "original_filename": null,
                              "file_size": null,
                              "status": "Not Finished",
                              "created_at": "2026-06-10T15:40:02.000000Z",
                              "cross_check_result": null,
                              "document_metadata": null,
                              "description": "Please upload an up-to-date shareholder registry",
                              "is_requested": true,
                              "ocr_data": null,
                              "is_console_upload": false,
                              "is_confirmed": true
                            }
                          ],
                          "groups": {
                            "LEGAL_PRESENCE": {
                              "total": 1,
                              "approved": 1,
                              "pending": 0,
                              "declined": 0,
                              "in_review": 0,
                              "other": 0,
                              "missing": 0
                            },
                            "OWNERSHIP_STRUCTURE": {
                              "total": 1,
                              "approved": 0,
                              "pending": 0,
                              "declined": 0,
                              "in_review": 0,
                              "other": 0,
                              "missing": 1
                            }
                          },
                          "required_groups": [
                            "LEGAL_PRESENCE",
                            "OWNERSHIP_STRUCTURE"
                          ],
                          "warnings": []
                        }
                      ],
                      "key_people_checks": [
                        {
                          "status": "In Review",
                          "node_id": "feature_kyb_key_people_1",
                          "registry": {
                            "officers": [
                              {
                                "uuid": "aaaa1111-bbbb-2222-cccc-333344445555",
                                "name": "Jane Smith",
                                "designation": "Director",
                                "role": "director",
                                "nationality": "British",
                                "appointment_date": "2015-03-12",
                                "termination_date": null,
                                "is_active": true,
                                "address": "1 Example Street, London, EC1A 1AA",
                                "aml_status": "Approved",
                                "kyc_status": "Approved",
                                "kyc_session_url": "https://verify.didit.me/session/abc123def456",
                                "kyc_session_id": "77777777-8888-9999-aaaa-bbbbbbbbbbbb",
                                "verification_workflow_type": "kyc",
                                "verification_workflow_id": "12121212-3434-5656-7878-909090909090",
                                "verification_workflow_label": "Key People KYC",
                                "verification_workflow_features": [
                                  {
                                    "feature": "ID_VERIFICATION",
                                    "status": "Approved"
                                  },
                                  {
                                    "feature": "LIVENESS",
                                    "status": "Approved"
                                  },
                                  {
                                    "feature": "AML",
                                    "status": "Approved"
                                  }
                                ],
                                "didit_internal_id": "99999999-0000-1111-2222-333333333333",
                                "kyc_document_type": "P",
                                "kyc_nationality": "GBR",
                                "kyc_liveness_passed": true,
                                "kyc_verified_at": "2026-06-10T14:22:31.123456Z",
                                "kyc_aml_categories": {
                                  "sanctions": "clear",
                                  "pep": "clear",
                                  "adverse_media": "clear",
                                  "warnings": "clear"
                                },
                                "kyc_notification_sent_at": "2026-06-09T09:00:00.000000Z"
                              }
                            ],
                            "beneficial_owners": [
                              {
                                "uuid": "bbbb2222-cccc-3333-dddd-444455556666",
                                "name": "John Doe",
                                "first_name": "John",
                                "last_name": "Doe",
                                "date_of_birth": "1980-05-04",
                                "country_of_birth": null,
                                "email": null,
                                "company_name": null,
                                "registration_number": null,
                                "entity_type": "person",
                                "nationality": "British",
                                "designation": null,
                                "roles": [
                                  "ubo",
                                  "shareholder"
                                ],
                                "ownership_min_shares": "50",
                                "ownership_max_shares": "75",
                                "is_active": true,
                                "aml_status": null,
                                "kyc_status": "In Progress",
                                "kyc_session_url": "https://verify.didit.me/session/def456ghi789",
                                "kyc_session_id": "88888888-9999-aaaa-bbbb-cccccccccccc",
                                "verification_workflow_type": "kyc",
                                "verification_workflow_id": "12121212-3434-5656-7878-909090909090",
                                "verification_workflow_label": "Key People KYC",
                                "verification_workflow_features": [
                                  {
                                    "feature": "ID_VERIFICATION",
                                    "status": "Not Finished"
                                  },
                                  {
                                    "feature": "LIVENESS",
                                    "status": "Not Finished"
                                  },
                                  {
                                    "feature": "AML",
                                    "status": "Not Finished"
                                  }
                                ],
                                "didit_internal_id": null,
                                "kyc_document_type": null,
                                "kyc_nationality": null,
                                "kyc_liveness_passed": null,
                                "kyc_verified_at": null,
                                "kyc_aml_categories": null,
                                "kyc_notification_sent_at": null,
                                "child_beneficial_owners": [],
                                "effective_ownership_percent": 75.0
                              }
                            ]
                          },
                          "submitted": {
                            "parties": [
                              {
                                "uuid": "cccc3333-dddd-4444-eeee-555566667777",
                                "entity_type": "person",
                                "source": "USER",
                                "name": "John Doe",
                                "first_name": "John",
                                "last_name": "Doe",
                                "company_name": null,
                                "registration_number": null,
                                "email": "john.doe@example.com",
                                "nationality": "GBR",
                                "phone_number": "+447700900123",
                                "date_of_birth": "1980-05-04",
                                "position": "Chief Executive Officer",
                                "custom_fields": {},
                                "is_active": true,
                                "is_skipped": false,
                                "requires_verification": true,
                                "roles": [
                                  {
                                    "role": "ubo",
                                    "ownership_percent": 75.0,
                                    "voting_percent": 75.0
                                  },
                                  {
                                    "role": "director",
                                    "ownership_percent": null,
                                    "voting_percent": null
                                  }
                                ],
                                "kyc_session_id": "88888888-9999-aaaa-bbbb-cccccccccccc",
                                "kyc_session_status": "In Progress",
                                "kyc_session_url": "https://verify.didit.me/session/def456ghi789",
                                "kyb_sub_session_id": null,
                                "kyb_sub_session_status": null,
                                "kyb_sub_session_url": null,
                                "verification_workflow_type": "kyc",
                                "verification_workflow_id": "12121212-3434-5656-7878-909090909090",
                                "verification_workflow_label": "Key People KYC",
                                "verification_workflow_features": [
                                  {
                                    "feature": "ID_VERIFICATION",
                                    "status": "Not Finished"
                                  },
                                  {
                                    "feature": "LIVENESS",
                                    "status": "Not Finished"
                                  },
                                  {
                                    "feature": "AML",
                                    "status": "Not Finished"
                                  }
                                ],
                                "didit_internal_id": null
                              }
                            ]
                          },
                          "ubo_kyc_summary": {
                            "total": 1,
                            "approved": 0,
                            "flagged": 0,
                            "pending": 1
                          },
                          "warnings": []
                        }
                      ],
                      "phone_verifications": null,
                      "email_verifications": null,
                      "questionnaire_responses": null,
                      "ip_analyses": null,
                      "reviews": [],
                      "contact_details": null,
                      "expected_details": {
                        "company_name": "Tesco PLC",
                        "registry_country": "GB",
                        "registration_number": "00445790"
                      },
                      "created_at": "2026-06-10T11:58:04.000000Z",
                      "expires_at": "2026-06-24T11:58:04.000000Z"
                    }
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/SessionDecision"
                }
              }
            }
          },
          "403": {
            "description": "Autentikasi atau otorisasi gagal. Kunci yang tidak ada mengembalikan `403`; kunci yang salah, dicabut, atau kedaluwarsa mengembalikan `401`. Dua string `detail` membedakan mode kegagalan:\n\n- `\"Authentication credentials were not provided or are invalid.\"` — tidak ada header `x-api-key` (dan tidak ada token `Authorization: Bearer`), atau kredensial yang diberikan gagal diintrospeksi (dicabut, kedaluwarsa, atau salah format).\n- `\"You do not have permission to perform this action.\"` — kredensial valid tetapi tidak diizinkan untuk membaca sesi ini: token Bearer pengguna konsol tidak memiliki izin `read:sessions` atau tidak dapat mengakses aplikasi pemilik, atau kunci API milik organisasi yang berbeda dari sesi tersebut.\n\nPerhatikan bahwa untuk `sessionId` yang benar-benar tidak dikenal, endpoint akan menyelesaikan aplikasi pemilik sebelum memvalidasi kredensial, sehingga sesi yang tidak ditemukan mengembalikan `404` bahkan ketika kredensial tidak ada atau tidak valid.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "example": "Authentication credentials were not provided or are invalid."
                    }
                  }
                },
                "examples": {
                  "Missing or invalid credentials": {
                    "summary": "Tidak ada header x-api-key, atau kunci gagal diintrospeksi",
                    "value": {
                      "detail": "Authentication credentials were not provided or are invalid."
                    }
                  },
                  "Insufficient permissions": {
                    "summary": "Kredensial valid yang tidak memiliki read:sessions atau akses ke aplikasi pemilik",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Sesi tidak ditemukan. Dikembalikan jika tidak ada sesi aktif yang cocok dengan `sessionId` yang diberikan baik sebagai sesi Verifikasi Pengguna (KYC) maupun Verifikasi Bisnis (KYB) — sesi yang telah dihapus juga masuk ke sini. Body respons berupa amplop standar `{\"detail\": ...}`.\n\n**Dua string `detail` yang berbeda.** Jika `sessionId` tidak diketahui baik sebagai sesi KYC maupun KYB, pencarian pemilik pra-autentikasi gagal dan Anda menerima `{\"detail\": \"Not found.\"}` — ini terjadi sebelum validasi kredensial, sehingga dikembalikan bahkan untuk panggilan tanpa autentikasi. Jika sesi ada tetapi tidak dapat diambil di bawah aplikasi yang diautentikasi (misalnya rekaman usang atau yang baru saja dihapus), tampilan mengembalikan `{\"detail\": \"Session not found.\"}`. Keduanya menunjukkan hasil yang sama — sesi tidak dapat diakses — jadi cocokkan dengan kode status `404` daripada string-nya.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "example": "Not found."
                    }
                  }
                },
                "examples": {
                  "Unknown session id": {
                    "summary": "sessionId tidak diketahui oleh aplikasi ini",
                    "value": {
                      "detail": "Not found."
                    }
                  },
                  "Session not retrievable": {
                    "summary": "Sesi ada tetapi tidak dapat diambil untuk aplikasi ini",
                    "value": {
                      "detail": "Session not found."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Batas laju terlampaui. Permintaan GET dibatasi hingga **600 per menit per kredensial** (kunci API, token Bearer, atau IP sumber saat tidak terautentikasi). Periksa `Retry-After` / `X-RateLimit-Reset` dan lakukan backoff sebelum mencoba lagi. Jika Anda mencapai batas ini saat melakukan polling untuk keputusan, beralihlah ke webhook `status.updated` dan ambil keputusan satu kali per perubahan status sebagai gantinya.",
            "headers": {
              "Retry-After": {
                "description": "Detik yang harus ditunggu sebelum mencoba lagi mengirimkan permintaan.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "example": 30
                }
              },
              "X-RateLimit-Limit": {
                "description": "Jumlah permintaan maksimum yang diizinkan dalam jendela saat ini (600 untuk permintaan GET).",
                "schema": {
                  "type": "integer",
                  "example": 600
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Permintaan yang tersisa dalam jendela saat ini.",
                "schema": {
                  "type": "integer",
                  "example": 0
                }
              },
              "X-RateLimit-Reset": {
                "description": "Timestamp Unix (detik) saat jendela saat ini direset.",
                "schema": {
                  "type": "integer",
                  "example": 1750000000
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "Penjelasan pelanggaran batas laju yang mudah dibaca manusia.",
                      "example": "GET request rate limit exceeded. You can make up to 600 requests per minute."
                    }
                  }
                },
                "examples": {
                  "Throttled": {
                    "summary": "Lebih dari 600 permintaan GET dalam satu menit dari kredensial yang sama",
                    "value": {
                      "detail": "GET request rate limit exceeded. You can make up to 600 requests per minute."
                    }
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "sessionId",
            "in": "path",
            "required": true,
            "description": "UUID sesi verifikasi yang keputusannya ingin Anda ambil. Ini adalah `session_id` yang dikembalikan oleh `POST /v3/session/`. Jalur yang sama berfungsi untuk sesi Verifikasi Pengguna (KYC) dan Verifikasi Bisnis (KYB) — server mencari ID tersebut di kedua jenis sesi.\n\n**Harus berupa UUID yang valid.** Rute ini hanya cocok dengan UUID yang terbentuk dengan benar, sehingga nilai yang salah format akan ditolak oleh router URL sebelum kode aplikasi apa pun berjalan dan responsnya berupa halaman **HTML** `404`, bukan struktur JSON `{\"detail\": ...}` yang ditunjukkan di bawah. Validasi format UUID di sisi klien sehingga Anda dapat membedakan kesalahan input dari `404` karena sesi benar-benar tidak ditemukan.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "11111111-2222-3333-4444-555555555555"
            }
          },
          {
            "name": "include",
            "in": "query",
            "required": false,
            "description": "Daftar bagian payload tambahan yang dipisahkan dengan koma. Nilai yang didukung: `events` dan `resubmissions`, sendiri atau bersama-sama (`events,resubmissions`). Saat `include=events` diteruskan, respons juga berisi linimasa event sesi (`events`, termasuk event perutean `WORKFLOW_BRANCH_EVALUATED` / `WORKFLOW_STATUS_NODE_REACHED` yang dijelaskan di halaman Retrieve Session), log aktivitas lengkap (`activity_reviews`), tanda daftar blokir (`blocklisted`), `cost_breakdown` per sesi, metadata alur kerja (`workflow_type`, `workflow_version`, `workflow_version_id`, dan `workflow_terminal_node_id` - node status alur kerja terakhir yang tercatat dan menetapkan status sesi, atau `null` jika belum ada yang tercatat; rekam jejak historis yang tidak dihapus oleh persetujuan, penolakan, atau pengajuan ulang manual, dan digantikan oleh node status alur kerja berikutnya), serta metadata sesi (`api_service` — string atau `null`, hanya ditetapkan untuk sesi API mandiri; `session_type` — `API`, `HOSTED`, atau `MIGRATED`; `has_device_nfc_support` — boolean). Dua kolom berubah relatif terhadap bentuk biasa: diskriminator `session_kind` tingkat atas **dihilangkan** (bentuk events hanya ada untuk sesi pengguna), dan array `features` beralih dari string biasa ke objek `{feature, node_id}` — di mana fitur email dilaporkan sebagai `EMAIL`, bukan `EMAIL_VERIFICATION`. Bentuk yang diperluas ini terutama digunakan oleh Konsol Didit; sebagian besar integrasi API sebaiknya tidak menyertakan parameter ini. **Batasan KYB:** `include=events` hanya berlaku untuk sesi pengguna (KYC). Sesi bisnis (`session_kind = \"business\"`) selalu mengembalikan bentuk keputusan bisnis standar — `events`, `activity_reviews`, `blocklisted`, `cost_breakdown` dan metadata `workflow_*`/sesi tambahan tidak pernah dikembalikan untuk sesi bisnis, dan array `features`-nya tetap berupa array string biasa. Dengan `include=resubmissions` (sesi pengguna maupun bisnis) respons juga berisi `resubmissions`: satu entri per permintaan pengajuan ulang, yang paling lama terlebih dahulu, masing-masing dengan `number`, `created_at`, `previous_status`, `nodes`, `reasons`, `requested_by`, dan `results` (apa yang dikembalikan oleh langkah-langkah yang diajukan ulang sebelum permintaan, dengan kunci yang sama dan dalam bentuk yang sama seperti hasil saat ini). Setiap item `cost_breakdown` memuat `usage_type`, `price`, `details`, dan `created_at`: langkah yang diajukan ulang yang dijalankan kembali akan ditagih sebagai item baru.",
            "schema": {
              "type": "string",
              "enum": [
                "events",
                "resubmissions",
                "events,resubmissions"
              ],
              "example": "events"
            }
          }
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL",
            "source": "curl -X GET 'https://verification.didit.me/v3/session/11111111-2222-3333-4444-555555555555/decision/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Accept: application/json'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.retrieve_decision(\n    \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.retrieveDecision(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.RetrieveDecision(ctx, \"11111111-2222-3333-4444-555555555555\", didit.SessionsRetrieveDecisionParams{})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().retrieveDecision(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->sessions->retrieveDecision('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.retrieve_decision(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.RetrieveDecisionAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/session/{sessionId}/delete/": {
      "delete": {
        "summary": "Hapus sesi verifikasi (KYC atau KYB)",
        "description": "Hapus satu sesi verifikasi, Verifikasi Pengguna (KYC) atau Verifikasi Bisnis (KYB), berdasarkan `session_id`-nya. ID tersebut dicari terlebih dahulu di antara sesi KYC, kemudian sesi KYB, sehingga kedua jenis sesi dihapus melalui satu URL ini.\n\n**Apa yang dihapus:**\n- Sesi dan setiap upaya verifikasi yang dimilikinya, termasuk hasil yang digantikan oleh pengiriman ulang: keputusan, data yang diekstrak, semua catatan fitur terkait (verifikasi identitas, wajah, liveness, pencocokan wajah, AML, pemeriksaan registri, analisis IP, dan sebagainya), peninjauan, serta log aktivitasnya.\n- Semua file tersimpan yang dimiliki oleh sesi: foto depan/belakang dokumen (varian penuh, terpotong, dan diburamkan untuk privasi), video pengambilan dokumen, potongan potret, potret chip NFC dan gambar tanda tangan, gambar referensi wajah, video liveness, gambar sumber/target pencocokan wajah, dokumen Bukti Alamat, dan file unggahan tambahan apa pun (KYC); dokumen perusahaan yang diunggah dan file tambahan (KYB). Dokumen Tanda Tangan Elektronik, PDF bertanda tangan, PDF bukti, dan gambar tanda tangan (KYC dan KYB): jalur unduhannya berhenti berfungsi. URL media yang diterbitkan sebelumnya (`https://<media-host>/...`) tidak lagi dapat di-resolve.\n- Data wajah sesi. Embedding wajahnya juga dihapus, kecuali jika Anda memilih untuk menyimpan templat tanpa gambar (lihat **Data biometrik wajah**).\n- Pengiriman webhook yang masih mengantre untuk sesi ini, serta percobaan ulangnya. Webhook yang sudah terkirim tidak terpengaruh.\n- Untuk sesi Verifikasi Bisnis (KYB): verifikasi yang dibuat untuk pihak kuncinya (KYC) dan pemilik perusahaannya (KYB), secara rekursif, dilaporkan sebagai `deleted_child_verifications`. Verifikasi yang hanya ditautkan, seperti KYC disetujui yang sudah ada dan digunakan kembali, tidak dihapus.\n\nSesi langsung menghilang dari setiap endpoint baca: `GET /v3/session/{sessionId}/decision/` mengembalikan `404` dan `GET /v3/sessions/` berhenti mencantumkannya. Pemantauan AML berkelanjutan dan pemantauan registri KYB yang dimulai oleh verifikasi yang dihapus akan berhenti.\n\n**Apa yang tidak terpengaruh:** entri daftar blokir yang dibuat dari sesi ini (wajah atau dokumen) **tidak** dihapus; kelola entri tersebut dengan endpoint daftar blokir. Token berbagi yang diterbitkan untuk sesi ini tidak dicabut, tetapi tidak ada lagi yang tersisa untuk diimpor: impor menggunakan token tersebut mengembalikan `400` dengan `{\"share_token\": [\"Original session does not exist.\"]}`. Kredit yang sudah digunakan **tidak** dikembalikan. Entitas Pengguna atau Bisnis induk **tidak** dihapus; gunakan `POST /v3/users/delete/` atau `POST /v3/businesses/delete/` untuk entitas tersebut. Jika potret profil Pengguna berasal dari sesi ini, potret tersebut akan dihapus bersamanya.\n\n**Data biometrik wajah:** secara default, embedding wajah sesi dihapus bersama sesi (`face_retention_outcome: deleted`). Aplikasi yang mengaktifkan retensi templat biometrik (`face_retention_policy: retain_until_user_deleted` pada `PATCH /v3/webhook/`), atau permintaan dengan `retain_face_embeddings: true`, menyimpan satu templat biometrik wajah tanpa gambar yang dikelola terpisah dan ditautkan ke Pengguna sesi (`retained_with_user`) agar deteksi duplikat, Pencarian Wajah, dan autentikasi biometrik tetap berfungsi. Templat ini tidak pernah berisi gambar wajah, media, kolom identitas, keputusan, atau ID sesi yang dihapus; ini adalah data biometrik yang dihapus pada `biometric_template_expires_at`, atau lebih awal saat penghapusan Pengguna, penghapusan privasi, atau pembersihan eksplisit melalui `/v3/biometric-templates/`. Sesi tanpa Pengguna yang ditautkan tidak dapat mempertahankan templat (`ineligible_no_vendor_user`). Kirim `deletion_instruction: privacy_erasure` untuk permintaan subjek data: ini menghapus setiap templat yang dipertahankan untuk Pengguna tersebut dan tidak pernah mempertahankan templat baru.\n\n**Tidak dapat dibatalkan:** penghapusan bersifat permanen dan tidak ada endpoint pemulihan. Ekspor apa pun yang Anda perlukan (misalnya PDF keputusan) sebelum Anda memanggilnya.\n\n**Efek samping:** tidak ada webhook yang dikirim untuk penghapusan.\n\n**Respons:** `200 OK` setelah penghapusan selesai, dengan isi JSON yang melaporkan `face_retention_outcome`, waktu kedaluwarsa templat yang dipertahankan, dan, untuk sesi KYB, `deleted_child_verifications`. Versi endpoint sebelumnya mengembalikan `204 No Content`; perbarui klien yang memeriksa `204`. Simpan `instruction_id` Anda di log penghapusan Anda sendiri.\n\n**Idempotensi:** tidak idempoten pada tingkat HTTP: panggilan pertama mengembalikan `200`; mengulanginya mengembalikan `404` karena sesi tidak lagi dapat ditemukan. Setelah `503`, sesi masih tetap ada; ulangi permintaan yang sama untuk menyelesaikan penghapusannya.\n\n**Autentikasi:** kirim kunci API aplikasi Anda di header `x-api-key`; sesi harus menjadi milik aplikasi tersebut. Token akses pengguna Konsol (`Authorization: Bearer ...`) juga dapat memanggil endpoint ini jika memiliki izin `delete:sessions`. Kegagalan autentikasi dan izin keduanya mengembalikan `403`; API ini tidak pernah mengembalikan `401`.\n\n**Batas laju:** kuota tulis bersama sebesar 300 permintaan/menit per kunci API di semua endpoint POST/PATCH/DELETE; melebihi batas ini akan mengembalikan `429`.\n\nUntuk menghapus sesi KYC secara massal berdasarkan `session_number` numeriknya, gunakan `POST /v3/sessions/delete/` sebagai gantinya.\n\n**Laporan regulasi yang diajukan:** jika data yang dipilih berada dalam laporan regulasi yang telah difinalisasi, seluruh permintaan ditolak dengan `409` dan tidak ada yang dihapus. Isinya menggunakan `code: in_filed_report` dan menyebutkan setiap laporan dengan `uuid`, `report_number`, `report_type`, dan `case_uuid`. Hapus laporan tersebut, lalu ulangi permintaan.",
        "operationId": "delete_v3_session_by_id",
        "x-didit-sdk": {
          "resource": "sessions",
          "method": "delete",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Sessions"
        ],
        "parameters": [
          {
            "in": "path",
            "name": "sessionId",
            "required": true,
            "description": "UUID (`session_id`) dari sesi Verifikasi Pengguna (KYC) atau Verifikasi Bisnis (KYB) yang akan dihapus, seperti yang dikembalikan saat sesi dibuat. Harus berupa UUID bertanda hubung kanonikal — nilai non-UUID tidak cocok dengan rute dan mengembalikan `404`.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "11111111-2222-3333-4444-555555555555"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Sesi dihapus. Isi respons melaporkan apa yang terjadi pada data biometrik wajah sesi tersebut dan, untuk sesi KYB, berapa banyak verifikasi yang dibuatnya yang ikut dihapus bersamanya.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "session_id": {
                      "type": "string",
                      "format": "uuid",
                      "description": "Sesi yang dihapus."
                    },
                    "session_number": {
                      "type": "integer",
                      "nullable": true,
                      "description": "Nomor sesi yang dihapus."
                    },
                    "face_retention_outcome": {
                      "type": "string",
                      "enum": [
                        "retained_with_user",
                        "deleted",
                        "none",
                        "ineligible_no_vendor_user"
                      ],
                      "description": "Hal yang terjadi pada data biometrik wajah sesi. `deleted`: embedding wajah dihapus bersama sesi (default). `retained_with_user`: sesi dihapus dan satu templat biometrik tanpa gambar tetap terhubung ke Pengguna; lihat `biometric_template_uuid`. `none`: sesi tidak memiliki embedding wajah (misalnya sesi KYB, atau sesi KYC tanpa swafoto dengan Deteksi Liveness). `ineligible_no_vendor_user`: retensi diminta tetapi sesi tidak memiliki Pengguna yang ditautkan, sehingga embedding dihapus bersama sesi. Kegagalan penyimpanan biometrik tidak pernah dilaporkan melalui kolom ini pada endpoint ini: endpoint akan mengembalikan `503` dan sesi tidak dihapus."
                    },
                    "biometric_template_uuid": {
                      "type": "string",
                      "format": "uuid",
                      "nullable": true,
                      "description": "Id templat biometrik yang disimpan saat `face_retention_outcome` adalah `retained_with_user`; jika tidak, bernilai `null`. Kelola melalui `/v3/biometric-templates/{template_uuid}/`."
                    },
                    "biometric_template_expires_at": {
                      "type": "string",
                      "format": "date-time",
                      "nullable": true,
                      "description": "Waktu templat biometrik yang disimpan dihapus, saat `face_retention_outcome` adalah `retained_with_user`; `null` jika tidak ada templat yang disimpan."
                    },
                    "deleted_child_verifications": {
                      "type": "integer",
                      "description": "Untuk sesi Verifikasi Bisnis (KYB): berapa banyak verifikasi yang dibuatnya (sesi KYC pihak kuncinya dan sesi KYB pemilik korporatnya, secara rekursif) yang dihapus bersamanya. Selalu `0` untuk sesi KYC."
                    }
                  }
                },
                "examples": {
                  "Deleted (default)": {
                    "value": {
                      "session_id": "4c5c7f3a-3b1d-4b7e-9c39-2b4f7e6a1d02",
                      "session_number": 1024,
                      "face_retention_outcome": "deleted",
                      "biometric_template_uuid": null,
                      "biometric_template_expires_at": null,
                      "deleted_child_verifications": 0
                    }
                  },
                  "Retained with User": {
                    "value": {
                      "session_id": "4c5c7f3a-3b1d-4b7e-9c39-2b4f7e6a1d02",
                      "session_number": 1024,
                      "face_retention_outcome": "retained_with_user",
                      "biometric_template_uuid": "9d2f4b6e-1c3a-4e8f-b7d5-0a1c2e3f4a5b",
                      "biometric_template_expires_at": "2027-10-09T10:15:00Z",
                      "deleted_child_verifications": 0
                    }
                  },
                  "Ineligible: no User": {
                    "summary": "Retensi diminta pada sesi yang dibuat tanpa vendor_data",
                    "value": {
                      "session_id": "7a1e9c2d-5f4b-4c3a-8e2d-1b0a9f8e7d6c",
                      "session_number": 1031,
                      "face_retention_outcome": "ineligible_no_vendor_user",
                      "biometric_template_uuid": null,
                      "biometric_template_expires_at": null,
                      "deleted_child_verifications": 0
                    }
                  },
                  "KYB session": {
                    "value": {
                      "session_id": "0f3c9b7e-2d1a-4e5f-8c6b-7a9d8e1f2c3b",
                      "session_number": 88,
                      "face_retention_outcome": "none",
                      "biometric_template_uuid": null,
                      "biometric_template_expires_at": null,
                      "deleted_child_verifications": 3
                    },
                    "summary": "Verifikasi bisnis yang dihapus bersama tiga verifikasi yang dibuat untuk pihak kuncinya"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Kesalahan validasi — tidak ada yang dihapus.",
            "content": {
              "application/json": {
                "examples": {
                  "Privacy erasure cannot retain": {
                    "value": {
                      "retain_face_embeddings": [
                        "Privacy erasure cannot retain biometric templates."
                      ]
                    }
                  },
                  "No finite retention duration": {
                    "summary": "Retensi diminta tanpa face_retention_days pada permintaan atau aplikasi",
                    "value": {
                      "detail": "A finite biometric-template retention duration is required."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Kegagalan autentikasi atau izin. Kunci yang hilang juga mengembalikan `403`; kunci yang salah, dicabut, atau kedaluwarsa mengembalikan `401`. Pengecualian: ketika `sessionId` tidak terhubung ke sesi aktif, pencarian pemilik pra-autentikasi akan mengembalikan `404` terlebih dahulu, bahkan jika kredensial tidak ada atau tidak valid.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Missing or invalid API key": {
                    "summary": "Tidak ada header x-api-key, atau kunci tidak valid",
                    "value": {
                      "detail": "Authentication credentials were not provided or are invalid."
                    }
                  },
                  "Insufficient permission": {
                    "summary": "Token pengguna tanpa delete:sessions, atau kredensial untuk aplikasi yang tidak memiliki sesi tersebut",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Tidak ada sesi KYC atau KYB di lingkungan produksi dengan `session_id` ini — ID tidak diketahui atau sesi sudah dihapus (mengulangi penghapusan yang berhasil akan mengarah ke sini).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Not Found": {
                    "summary": "Sesi tidak dikenal atau sudah dihapus",
                    "value": {
                      "detail": "Not found."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Batas laju penulisan bersama terlampaui (300 permintaan POST/PATCH/DELETE per menit per kunci API). Periksa header respons `Retry-After` dan `X-RateLimit-*` sebelum mencoba lagi.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Rate limited": {
                    "summary": "Anggaran penulisan habis",
                    "value": {
                      "detail": "Write request rate limit exceeded. You can make up to 300 requests per minute."
                    }
                  }
                }
              }
            }
          },
          "503": {
            "description": "Penghapusan tidak dapat diselesaikan karena layanan penyimpanan, penyimpanan biometrik, atau penyedia pemantauan tidak tersedia. Sesi masih tetap ada; ulangi permintaan yang sama hingga mengembalikan `200`. Beberapa file yang disimpan atau embedding wajahnya mungkin sudah dihapus, jadi jangan mengandalkannya setelah `503`. Percobaan ulang menghasilkan satu templat yang sama.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Session deletion unavailable": {
                    "summary": "Layanan penyimpanan atau penyedia pemantauan tidak tersedia",
                    "value": {
                      "detail": "The session could not be deleted because a storage service or a monitoring provider is unavailable. The session is still in place; repeat the request to finish deleting it."
                    }
                  },
                  "Biometric store unavailable": {
                    "summary": "Penyimpanan biometrik tidak tersedia saat mempertahankan atau menghapus total templat",
                    "value": {
                      "detail": "The biometric-template operation could not finish because an external store is unavailable. The operation is retryable."
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "Sesi merupakan bagian dari laporan regulasi yang telah diselesaikan. Tidak ada yang dihapus.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InFiledReportError"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl (default policy)",
            "source": "curl -X DELETE \\\n  https://verification.didit.me/v3/session/11111111-2222-3333-4444-555555555555/delete/ \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "curl",
            "label": "curl (retain template)",
            "source": "curl -X DELETE \\\n  https://verification.didit.me/v3/session/11111111-2222-3333-4444-555555555555/delete/ \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"retain_face_embeddings\": true, \"face_retention_days\": 365}'"
          },
          {
            "lang": "curl",
            "label": "curl (privacy erasure)",
            "source": "curl -X DELETE \\\n  https://verification.didit.me/v3/session/11111111-2222-3333-4444-555555555555/delete/ \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"deletion_instruction\": \"privacy_erasure\", \"instruction_id\": \"dsar-2026-0142\"}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.delete(\n    \"11111111-2222-3333-4444-555555555555\",\n    retain_face_embeddings=True,\n    face_retention_days=365,\n    instruction_id=\"post-approval-cleanup-2026-08\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.delete(\"11111111-2222-3333-4444-555555555555\", {\n  retain_face_embeddings: true,\n  face_retention_days: 365,\n  instruction_id: \"post-approval-cleanup-2026-08\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.Delete(ctx, \"11111111-2222-3333-4444-555555555555\", didit.SessionsDeleteParams{\n\tRetainFaceEmbeddings: didit.Bool(true),\n\tFaceRetentionDays:    didit.Int(365),\n\tInstructionID:        didit.String(\"post-approval-cleanup-2026-08\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.SessionsDeleteParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().delete(\"11111111-2222-3333-4444-555555555555\", SessionsDeleteParams.builder()\n        .retainFaceEmbeddings(true)\n        .faceRetentionDays(365L)\n        .instructionId(\"post-approval-cleanup-2026-08\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->sessions->delete('11111111-2222-3333-4444-555555555555', [\n    'retain_face_embeddings' => true,\n    'face_retention_days' => 365,\n    'instruction_id' => 'post-approval-cleanup-2026-08',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.delete(\n  \"11111111-2222-3333-4444-555555555555\",\n  retain_face_embeddings: true,\n  face_retention_days: 365,\n  instruction_id: \"post-approval-cleanup-2026-08\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.DeleteAsync(\"11111111-2222-3333-4444-555555555555\", new SessionsDeleteParams\n{\n    RetainFaceEmbeddings = true,\n    FaceRetentionDays = 365,\n    InstructionId = \"post-approval-cleanup-2026-08\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "requestBody": {
          "required": false,
          "description": "Opsional. Abaikan payload sepenuhnya untuk mengikuti kebijakan retensi data aplikasi dengan penghapusan operasional.",
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "retain_face_embeddings": {
                    "type": "boolean",
                    "nullable": true,
                    "description": "Timpa `face_retention_policy` aplikasi untuk penghapusan ini. `true` mempertahankan satu templat biometrik wajah bebas gambar yang ditautkan ke Pengguna sesi setelah sesi dihapus; `false` menghapus embedding wajah bersama sesi; abaikan atau gunakan `null` untuk mengikuti kebijakan aplikasi. Diabaikan untuk sesi KYB dan untuk sesi tanpa embedding wajah.",
                    "example": true
                  },
                  "face_retention_days": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 3650,
                    "description": "Durasi retensi terbatas, dalam hari, untuk templat yang disimpan. Wajib diisi saat templat disimpan kecuali aplikasi sudah menyetel `face_retention_days`. `expires_at` templat adalah yang paling awal di antara durasi ini, jendela retensi data umum aplikasi, dan `face_retention_deadline`.",
                    "example": 365
                  },
                  "face_retention_deadline": {
                    "type": "string",
                    "format": "date-time",
                    "description": "Kedaluwarsa mutlak opsional untuk templat yang disimpan. Harus berada di masa mendatang.",
                    "example": "2027-08-28T00:00:00Z"
                  },
                  "deletion_instruction": {
                    "type": "string",
                    "enum": [
                      "operational_session_delete",
                      "privacy_erasure"
                    ],
                    "default": "operational_session_delete",
                    "description": "Kelas instruksi yang Anda berikan. `operational_session_delete` menghapus sesi dan mempertahankan templat hanya jika kebijakan atau `retain_face_embeddings` menentukannya. `privacy_erasure` menghapus permanen setiap templat biometrik tersimpan yang terkait dengan Pengguna sesi tersebut sebelum menghapus sesi, tidak dapat ditimpa oleh kebijakan aplikasi, dan tidak dapat digabungkan dengan `retain_face_embeddings: true` (`400`).",
                    "example": "operational_session_delete"
                  },
                  "instruction_id": {
                    "type": "string",
                    "maxLength": 255,
                    "description": "Referensi permanen Anda untuk instruksi penghapusan ini (misalnya id tiket penghapusan). Dicatat pada jejak audit dan pada setiap templat yang dipertahankan. Dihasilkan oleh Didit jika ditiadakan.",
                    "example": "dsar-2026-0142"
                  }
                }
              },
              "examples": {
                "Retain a biometric template": {
                  "summary": "Hapus sesi, simpan templat tanpa gambar selama 365 hari",
                  "value": {
                    "retain_face_embeddings": true,
                    "face_retention_days": 365,
                    "instruction_id": "post-approval-cleanup-2026-08"
                  }
                },
                "Force deletion on an opted-in application": {
                  "summary": "Hapus embedding wajah terlepas dari kebijakan aplikasi",
                  "value": {
                    "retain_face_embeddings": false
                  }
                },
                "Privacy erasure": {
                  "summary": "Permintaan subjek data: hapus sesi dan bersihkan setiap templat yang disimpan untuk orang tersebut",
                  "value": {
                    "deletion_instruction": "privacy_erasure",
                    "instruction_id": "dsar-2026-0142"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v3/session/{sessionId}/generate-pdf/": {
      "get": {
        "summary": "Unduh laporan PDF untuk sesi verifikasi",
        "description": "Render dan unduh laporan PDF siap kepatuhan untuk sesi verifikasi yang telah selesai. Jalur yang sama melayani sesi Verifikasi Pengguna (KYC) dan Verifikasi Bisnis (KYB) — server mencocokkan `sessionId` terhadap kedua jenis sesi dan memilih templat laporan yang sesuai.\n\n**Status yang memenuhi syarat.** Sesi harus sudah memiliki status final atau yang dapat ditinjau:\n\n- Sesi KYC: `Approved`, `Declined`, `In Review`, atau `Kyc Expired`.\n- Sesi KYB: `Approved`, `Declined`, atau `In Review`.\n\nStatus lainnya (`Not Started`, `In Progress`, `Expired`, `Abandoned`, …) mengembalikan `403` dengan string `detail` penjelas — lihat respons `403` di bawah.\n\n**Isi laporan.** PDF mencerminkan tampilan sesi konsol pada saat permintaan dibuat:\n\n- **KYC** — status sesi yang diagregasi, daftar peringatan, dan satu bagian per fitur yang dijalankan: Verifikasi Identitas (gambar dokumen beserta kolom yang diekstraksi), NFC, Deteksi Liveness, Pencocokan Wajah, Verifikasi Email, Verifikasi Telepon, Bukti Alamat, jawaban Kuesioner, Validasi Database, Skrining AML, dan Analisis IP — diikuti oleh tag sesi, aktivitas peninjauan konsol (komentar dan perubahan status), serta linimasa peristiwa sesi.\n- **KYB** — pemeriksaan registri (data perusahaan), skrining AML, verifikasi dokumen bisnis, pemeriksaan pihak kunci, tanggapan kuesioner, verifikasi telepon/email, analisis IP, dan linimasa peristiwa sesi, diikuti oleh tag dan aktivitas peninjauan.\n\n**Branding.** Jika aplikasi Anda memiliki kustomisasi White Label, laporan akan dirender dengan logo Anda dan tautan ke URL kebijakan privasi Anda; jika tidak, laporan akan menggunakan branding Didit. Laporan dirender dalam bahasa Inggris — tidak ada parameter bahasa.\n\n**Tanpa penyimpanan cache.** Setiap panggilan merender ulang PDF dari data sesi saat ini, sehingga laporan yang dibuat setelah peninjauan manual mencerminkan keputusan peninjau. Dua panggilan untuk sesi yang sama dapat menghasilkan file dengan byte yang berbeda — arsipkan file yang diunduh jika Anda memerlukan salinan yang tidak dapat diubah (immutable).\n\n**Latensi.** Proses render mengunduh setiap gambar yang disimpan (sisi dokumen, swafoto, file tambahan) sebelum menyusun PDF, sehingga sesi dengan banyak media dapat memakan waktu beberapa detik. Gunakan batas waktu baca klien yang longgar (disarankan 60 dtk) dan alirkan isi respons ke disk.\n\n**Garis miring penutup.** Rute kanonis diakhiri dengan garis miring penutup (`…/generate-pdf/`). Permintaan tanpanya akan dilayani langsung dengan respons yang sama — tidak ada pengalihan `301`, sehingga klien tidak perlu mengikuti pengalihan dan `curl` tidak memerlukan `-L`. Gunakan URL dengan garis miring seperti pada contoh.\n\nJika Anda memerlukan data yang mendasari dalam format JSON alih-alih laporan yang dirender, gunakan `GET /v3/session/{sessionId}/decision/`. Untuk semua sesi yang dapat dilaporkan dari satu pengguna dalam satu dokumen tunggal, gunakan `GET /v3/users/{vendor_data}/generate-pdf/`.",
        "operationId": "get_v3_session_generate_pdf",
        "x-didit-sdk": {
          "resource": "sessions",
          "method": "generate_pdf",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Sessions"
        ],
        "parameters": [
          {
            "name": "sessionId",
            "in": "path",
            "required": true,
            "description": "UUID dari sesi Verifikasi Pengguna (KYC) atau Verifikasi Bisnis (KYB) yang akan dirender — `session_id` yang dikembalikan oleh `POST /v3/session/`. Path yang sama berlaku untuk kedua jenis sesi; gunakan nama file `Content-Disposition` pada respons untuk mengetahui jenis laporan yang Anda terima.\n\n**Harus berupa UUID huruf kecil dengan format yang benar.** Rute ini hanya cocok dengan UUID yang valid, sehingga nilai yang salah format akan ditolak oleh router URL sebelum kode aplikasi apa pun berjalan dan responsnya adalah halaman **HTML** `404`, bukan envelope JSON `{\"detail\": ...}` yang ditunjukkan di bawah ini. Pengonversi UUID rute hanya cocok dengan bentuk huruf kecil kanonikal — UUID heksadesimal huruf besar akan ditolak dengan HTML 404.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "11111111-2222-3333-4444-555555555555"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Dokumen PDF hasil render, dikembalikan langsung sebagai biner `application/pdf` — tidak ada pembungkus JSON dan tidak ada pengalihan URL unduhan. Isi dimulai dengan magic bytes `%PDF` (PDF 1.7). Simpan ke file `.pdf` atau alirkan langsung ke pemanggil Anda.",
            "headers": {
              "Content-Disposition": {
                "description": "`attachment; filename=session_{sessionId}.pdf` untuk sesi KYC, `attachment; filename=business_{sessionId}.pdf` untuk sesi KYB — prefiks memberi tahu Anda templat laporan mana yang dirender.",
                "schema": {
                  "type": "string",
                  "example": "attachment; filename=session_11111111-2222-3333-4444-555555555555.pdf"
                }
              },
              "Content-Length": {
                "description": "Ukuran total PDF dalam byte; badan respons tidak dibagi menjadi beberapa chunk.",
                "schema": {
                  "type": "integer",
                  "example": 25191
                }
              }
            },
            "content": {
              "application/pdf": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "403": {
            "description": "Kegagalan autentikasi, otorisasi, atau status sesi. Kunci yang hilang mengembalikan `403`; kunci yang salah, dicabut, atau kedaluwarsa mengembalikan `401`. Bedakan jenis kegagalan berdasarkan string `detail`:\n\n- `\"Authentication credentials were not provided or are invalid.\"` — tidak ada header `x-api-key` (dan tidak ada token `Authorization: Bearer`), atau kredensial yang diberikan gagal diintrospeksi (dicabut, kedaluwarsa, atau format salah).\n- `\"You do not have permission to perform this action.\"` — kredensial valid tetapi tidak dapat membaca sesi ini: token Bearer pengguna konsol tidak memiliki izin `read:sessions` atau tidak dapat mengakses aplikasi pemilik, atau kunci API milik organisasi yang berbeda dari sesi tersebut.\n- `\"You can only generate a PDF for sessions in review, declined, approved or kyc expired\"` — sesi KYC ada tetapi belum berada dalam status yang memenuhi syarat (misalnya `Not Started` atau `In Progress`). Tunggu webhook `status.updated` sebelum meminta laporan.\n- `\"You can only generate a PDF for sessions in review, declined or approved\"` — kondisi yang sama untuk sesi KYB.\n\nPerhatikan bahwa untuk `sessionId` yang sama sekali tidak dikenal, endpoint akan mencari aplikasi pemilik sebelum memvalidasi kredensial, sehingga sesi yang tidak ditemukan mengembalikan `404` bahkan ketika kredensial tidak ada atau tidak valid.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "example": "You can only generate a PDF for sessions in review, declined, approved or kyc expired"
                    }
                  }
                },
                "examples": {
                  "Missing or invalid credentials": {
                    "summary": "Tidak ada header x-api-key, atau kunci gagal diintrospeksi",
                    "value": {
                      "detail": "Authentication credentials were not provided or are invalid."
                    }
                  },
                  "Insufficient permissions": {
                    "summary": "Kredensial valid yang tidak memiliki read:sessions atau akses ke aplikasi pemilik",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "KYC session not finished": {
                    "summary": "Sesi KYC masih Belum Dimulai / Sedang Berlangsung",
                    "value": {
                      "detail": "You can only generate a PDF for sessions in review, declined, approved or kyc expired"
                    }
                  },
                  "KYB session not finished": {
                    "summary": "Sesi KYB masih Belum Dimulai / Sedang Berlangsung",
                    "value": {
                      "detail": "You can only generate a PDF for sessions in review, declined or approved"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Tidak ada sesi aktif dengan `sessionId` ini — sesi tidak pernah dibuat, atau telah dihapus. Resolusi pemilik dilakukan sebelum validasi kredensial, sehingga `404` ini tetap dikembalikan bahkan untuk permintaan tanpa autentikasi. Bergantung pada pencarian mana yang tidak menemukan hasil, string `detail` adalah `\"Not found.\"` (kasus umum) atau `\"Session not found.\"`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "example": "Not found."
                    }
                  }
                },
                "examples": {
                  "Unknown session": {
                    "summary": "sessionId tidak cocok dengan sesi KYC atau KYB apa pun",
                    "value": {
                      "detail": "Not found."
                    }
                  },
                  "Recently deleted session": {
                    "summary": "Sesi telah dihapus di antara pencarian",
                    "value": {
                      "detail": "Session not found."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Batas laju terlampaui. Pembuatan PDF memiliki batas khusus sebesar **50 permintaan per menit per kredensial** (kunci API, token Bearer, atau IP sumber saat tidak terautentikasi), selain batas GET global 600/menit. Tunggu selama `Retry-After` detik (juga tercermin dalam header `X-RateLimit-*`), lalu coba lagi. Laporan tidak di-cache di sisi server, jadi unduh setiap laporan satu kali dan simpan filenya alih-alih mengambilnya kembali.",
            "headers": {
              "Retry-After": {
                "description": "Detik yang harus ditunggu sebelum mencoba lagi mengirimkan permintaan.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "example": 30
                }
              },
              "X-RateLimit-Limit": {
                "description": "Jumlah maksimum pembuatan PDF yang diizinkan dalam jendela saat ini (50).",
                "schema": {
                  "type": "integer",
                  "example": 50
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Permintaan yang tersisa dalam jendela saat ini.",
                "schema": {
                  "type": "integer",
                  "example": 0
                }
              },
              "X-RateLimit-Reset": {
                "description": "Timestamp Unix (detik) saat jendela saat ini direset.",
                "schema": {
                  "type": "integer",
                  "example": 1750000000
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "Penjelasan pelanggaran batas laju yang mudah dibaca manusia.",
                      "example": "Session PDF generation rate limit exceeded. You can make up to 50 requests per minute."
                    }
                  }
                },
                "examples": {
                  "Throttled": {
                    "summary": "Lebih dari 50 pembuatan PDF dalam satu menit dari kredensial yang sama",
                    "value": {
                      "detail": "Session PDF generation rate limit exceeded. You can make up to 50 requests per minute."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL",
            "source": "curl --fail \\\n  https://verification.didit.me/v3/session/11111111-2222-3333-4444-555555555555/generate-pdf/ \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  --output report.pdf"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\ncontent = client.sessions.generate_pdf(\n    \"11111111-2222-3333-4444-555555555555\",\n)\nwith open(\"download.pdf\", \"wb\") as file:\n    file.write(content)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import { writeFile } from \"node:fs/promises\";\nimport Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst content = await didit.sessions.generatePdf(\"11111111-2222-3333-4444-555555555555\");\nawait writeFile(\"download.pdf\", Buffer.from(await content.arrayBuffer()));"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresp, err := client.Sessions.GeneratePDF(ctx, \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\ndefer resp.Body.Close()\nfile, err := os.Create(\"download.pdf\")\nif err != nil {\n\tlog.Fatal(err)\n}\ndefer file.Close()\nif _, err := io.Copy(file, resp.Body); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.nio.file.Path;\nimport me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nclient.sessions().generatePdf(\"11111111-2222-3333-4444-555555555555\")\n        .writeTo(Path.of(\"download.pdf\"));"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$content = $didit->sessions->generatePdf('11111111-2222-3333-4444-555555555555');\n$content->saveTo('download.pdf');"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ncontent = didit.sessions.generate_pdf(\"11111111-2222-3333-4444-555555555555\")\nFile.binwrite(\"download.pdf\", content)"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar content = await client.Sessions.GeneratePdfAsync(\"11111111-2222-3333-4444-555555555555\");\nawait content.SaveToAsync(\"download.pdf\");"
          }
        ]
      }
    },
    "/v3/session/{sessionId}/sandbox/arm/": {
      "post": {
        "summary": "Siapkan skenario sandbox pada sesi",
        "description": "Simpan skenario sandbox pada sesi `Not Started` dan perluas nilai khusus yang disertakan (email, telepon, atau kolom `expected_details`) ke sesi tersebut, sehingga penyedia tiruan mereproduksi hasil skenario setelah alur berjalan. Ini adalah endpoint yang dipanggil oleh pemilih skenario pra-alur di UI verifikasi yang di-hosting Didit saat penguji memilih hasil sebelum memulai pengambilan. Buat pemilih Anda sendiri menggunakan endpoint ini, atau panggil langsung dari test harness sandbox.\n\nAutentikasi dengan `Session-Token` milik sesi itu sendiri (dikembalikan di `session_token` oleh [Create Session](/id/sessions-api/create-session)), bukan `x-api-key` aplikasi Anda: endpoint ini dimaksudkan untuk dipanggil dari klien, bukan backend Anda. Skenario hanya diterima saat `status` adalah `Not Started`. Memanggilnya kembali saat masih `Not Started` akan mempersiapkan ulang (re-arm) sesi: tindakan ini menukar nilai khusus skenario baru dan hanya menghapus nilai yang ditulis oleh skenario *sebelumnya*, sehingga nilai apa pun yang telah diketik pengguna secara manual (email, nama depan, dll.) tetap tersimpan setelah penyiapan ulang. Mempersiapkan sesi yang telah melewati `Not Started`, atau yang termasuk dalam aplikasi live (non-sandbox), akan ditolak.\n\nLihat [Sandbox & Test Data](/id/integration/sandbox-testing) untuk katalog skenario lengkap dan dua cara lain untuk mendorong hasil: `sandbox_scenario` saat pembuatan sesi, dan mengetik nilai khusus secara langsung.",
        "operationId": "post_v3_session_sandbox_arm",
        "x-didit-sdk": {
          "resource": "sessions",
          "method": "arm_sandbox",
          "auth": "device_token",
          "server": false
        },
        "tags": [
          "Sessions"
        ],
        "security": [
          {
            "SessionTokenAuth": []
          }
        ],
        "parameters": [
          {
            "in": "path",
            "name": "sessionId",
            "required": true,
            "description": "UUID sesi verifikasi sandbox yang akan diaktifkan. Harus cocok dengan sesi yang dienkode dalam Session-Token yang digunakan untuk mengautentikasi.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "11111111-2222-3333-4444-555555555555"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "scenario"
                ],
                "properties": {
                  "scenario": {
                    "type": "string",
                    "description": "Slug skenario yang akan disiapkan. Lihat katalog di GET /v1/sandbox/scenarios/ atau tabel skenario di [Sandbox & Data Uji](/id/integration/sandbox-testing).",
                    "example": "decline_document_expired"
                  }
                }
              },
              "examples": {
                "Arm": {
                  "summary": "Siapkan skenario temuan PEP AML",
                  "value": {
                    "scenario": "decline_aml_hit"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Skenario diaktifkan. Nilai ajaibnya sekarang berada pada sesi. `status` mencerminkan status sesi saat ini, yang tidak pernah diubah oleh panggilan ini: nilainya selalu `Not Started` saat berhasil.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "session_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "scenario": {
                      "type": "string",
                      "description": "Slug skenario yang diaktifkan (mencerminkan permintaan)."
                    },
                    "status": {
                      "type": "string",
                      "example": "Not Started"
                    }
                  }
                },
                "examples": {
                  "Armed": {
                    "summary": "Skenario diaktifkan pada sesi Not Started",
                    "value": {
                      "session_id": "11111111-2222-3333-4444-555555555555",
                      "scenario": "decline_aml_hit",
                      "status": "Not Started"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Kesalahan validasi: slug skenario tidak dikenal, atau sesi telah berjalan melewati `Not Started`.",
            "content": {
              "application/json": {
                "examples": {
                  "Unknown Scenario": {
                    "summary": "skenario tidak ada di dalam katalog",
                    "value": {
                      "scenario": [
                        "Unknown sandbox scenario: 'not-a-real-scenario'."
                      ]
                    }
                  },
                  "Already Started": {
                    "summary": "Sesi telah melewati Not Started",
                    "value": [
                      "Scenario can only be armed before the verification starts."
                    ]
                  }
                }
              }
            }
          },
          "404": {
            "description": "Session-Token tidak mengarah ke `session_id` ini, atau sesi tersebut milik aplikasi produksi (non-sandbox).",
            "content": {
              "application/json": {
                "examples": {
                  "Not Found": {
                    "summary": "Sesi langsung, atau ketidakcocokan session_id / token",
                    "value": {
                      "detail": "Not found."
                    }
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST \\\n  https://verification.didit.me/v3/session/11111111-2222-3333-4444-555555555555/sandbox/arm/ \\\n  -H 'Session-Token: YOUR_SESSION_TOKEN' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"scenario\": \"decline_aml_hit\"\n  }'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "import requests\n\nresponse = requests.post(\n    \"https://verification.didit.me/v3/session/11111111-2222-3333-4444-555555555555/sandbox/arm/\",\n    headers={\n        \"Session-Token\": \"YOUR_SESSION_TOKEN\",\n        \"Content-Type\": \"application/json\",\n    },\n    json={\"scenario\": \"decline_aml_hit\"},\n)\nresponse.raise_for_status()\nprint(response.json())  # {'session_id': '...', 'scenario': 'decline_aml_hit', 'status': 'Not Started'}"
          },
          {
            "lang": "javascript",
            "label": "JavaScript",
            "source": "const response = await fetch(\n  'https://verification.didit.me/v3/session/11111111-2222-3333-4444-555555555555/sandbox/arm/',\n  {\n    method: 'POST',\n    headers: {\n      'Session-Token': sessionToken,\n      'Content-Type': 'application/json',\n    },\n    body: JSON.stringify({ scenario: 'decline_aml_hit' }),\n  },\n);\nif (!response.ok) throw new Error(`HTTP ${response.status}`);\nconst { session_id, scenario, status } = await response.json();"
          }
        ]
      }
    },
    "/v3/session/{sessionId}/update-status/": {
      "patch": {
        "summary": "Setujui, tolak, atau minta pengiriman ulang untuk sesi verifikasi",
        "description": "Ganti keputusan akhir sesi verifikasi KYC atau KYB secara manual. Atur `new_status` ke `Approved` atau `Declined` untuk mencatat keputusan manual, atau ke `Resubmitted` untuk mengosongkan langkah verifikasi tertentu dan mengizinkan pengguna mengulanginya melalui URL verifikasi yang sama. Endpoint ini menerima ID sesi pengguna (KYC) dan bisnis (KYB).\n\nPanggil endpoint ini setelah sesi mencapai status yang dapat ditinjau: status saat ini harus berupa `Approved`, `Declined`, `In Review`, `Kyc Expired`, `Abandoned`, atau `Resubmitted`. Sesi yang masih `Not Started`, `In Progress`, atau `Awaiting User`, atau yang berakhir sebagai `Expired`, akan mengembalikan `400`. Kunci API Anda memerlukan izin `write:sessions` (kunci API dengan cakupan memerlukan akses tulis ke keputusan). Pemeriksaan status yang memenuhi syarat berjalan sebelum validasi isi permintaan, sehingga sesi yang tidak memenuhi syarat mengembalikan kesalahan `Wrong Current Status` meskipun payload juga tidak valid.\n\nUntuk `Resubmitted`, teruskan `nodes_to_resubmit` untuk memilih langkah alur kerja mana yang harus diulangi pengguna, atau hilangkan parameter ini untuk memilih otomatis upaya fitur yang ada dalam status yang dapat dikirim ulang (`Declined`, `In Review`, `Not Finished`, `Expired`). Fitur yang belum pernah dicoba tidak akan dipilih secara otomatis: cantumkan secara eksplisit di `nodes_to_resubmit`, atau permintaan mengembalikan `400` jika tidak ada upaya tercatat yang perlu dikirim ulang. Hasil sebelumnya dari langkah yang dipilih akan dipindahkan ke riwayat pengiriman ulang (dikembalikan oleh Dapatkan Keputusan dengan `include=resubmissions`), langkah-langkah diurutkan ulang agar sesuai dengan graf alur kerja, batas waktu kedaluwarsa sesi dimulai ulang, dan URL verifikasi asli dapat digunakan kembali. Langkah khusus backend (`AML`, `DATABASE_VALIDATION`, `IP_ANALYSIS`) di bagian awal daftar langsung dijalankan tanpa interaksi pengguna; jika setiap langkah yang dikirim ulang merupakan langkah khusus backend, sesi akan diselesaikan ulang dalam permintaan yang sama. `KYB_REGISTRY` dan `KYB_KEY_PEOPLE` tidak dapat dikirim ulang secara langsung: kirim ulang sesi KYC turunan yang relevan dan sesi bisnis induk akan dihitung ulang secara otomatis.\n\nSetiap panggilan yang mengubah status akan memicu [webhook](/id/integration/webhooks) `status.updated` setelah perubahan diterapkan dan menambahkan entri aktivitas (dengan atribusi pelaku dan `comment` Anda) ke `reviews` sesi, yang terlihat di [Dapatkan Keputusan](#get-/v3/session/-sessionId-/decision/) dan di linimasa aktivitas konsol. Agregat profil pengguna yang ditautkan ke `vendor_data` sesi juga diperbarui. Penolakan akan menonaktifkan pemantauan AML berkelanjutan untuk sesi tersebut; menyetujui ulang akan mengaktifkannya kembali (dari `Resubmitted`, `Declined`, atau `Kyc Expired`) saat pemantauan diaktifkan pada alur kerja. Menyetujui atau menolak KYC turunan milik pemeriksaan pihak kunci KYB akan menghitung ulang status sesi bisnis induk. Tetapkan `send_email: true` (dengan `email_address`) untuk memberi tahu pengguna: pemberitahuan status untuk `Approved`/`Declined`, atau email pengiriman ulang yang berisi tautan verifikasi dan alasan per langkah untuk `Resubmitted`. Untuk memeriksa email terlebih dahulu, pratinjau dengan [Pratinjau Email Keputusan](/id/sessions-api/preview-decision-email) (`Approved`, `Declined`) atau [Pratinjau Email Pengiriman Ulang](/id/sessions-api/preview-resubmission) (`Resubmitted`) dan teruskan `preview_token` miliknya sebagai `email_preview_token`: pembaruan kemudian mengirimkan email persis seperti yang dipratinjau, atau mengembalikan `409` sebelum mengubah apa pun jika email atau sesi telah berubah sejak pratinjau atau tanda terima berusia lebih dari 15 menit.\n\nMengulangi `Approved` atau `Declined` pada sesi yang sudah memiliki status tersebut tidak akan mengubah apa pun dan mengembalikan `200`: tidak ada webhook, entri aktivitas, maupun email. Mengulangi `Resubmitted` mengembalikan `400` (`The new status is the same as the current status.`). Kredensial yang hilang atau tidak valid serta izin yang hilang mengembalikan `403`; kunci API dengan cakupan yang kedaluwarsa mengembalikan `401`.",
        "operationId": "patch_v3_session_update_status",
        "x-didit-sdk": {
          "resource": "sessions",
          "method": "update_status",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Sessions"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "in": "path",
            "name": "sessionId",
            "required": true,
            "description": "UUID sesi verifikasi yang akan diperbarui. Menerima ID sesi pengguna (KYC) dan bisnis (KYB) — layanan mencari ID tersebut di kedua jenis sesi.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "11111111-2222-3333-4444-555555555555"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "new_status"
                ],
                "properties": {
                  "new_status": {
                    "type": "string",
                    "description": "Status target. `Approved` dan `Declined` mencatat keputusan manual akhir (masing-masing juga dapat membatalkan yang lain). `Resubmitted` menghapus langkah-langkah yang dipilih dan mengirimkan sesi kembali ke pengguna. Nilai lainnya mengembalikan `400`.",
                    "enum": [
                      "Approved",
                      "Declined",
                      "Resubmitted"
                    ],
                    "example": "Approved"
                  },
                  "comment": {
                    "type": "string",
                    "description": "Alasan teks bebas untuk perubahan tersebut, disimpan pada jejak peninjauan sesi dan dikembalikan dalam array `reviews` pada [Dapatkan Keputusan](#get-/v3/session/-sessionId-/decision/). Misalnya `Duplicated user`.",
                    "example": "All checks passed manual review"
                  },
                  "nodes_to_resubmit": {
                    "type": "array",
                    "description": "Langkah alur kerja yang harus diulang oleh pengguna. Hanya ditindaklanjuti ketika `new_status` bernilai `Resubmitted`. Untuk `Approved`/`Declined`, entri tetap divalidasi skemanya (nilai `feature` yang tidak valid mengembalikan `400`), tetapi entri yang valid secara skema diabaikan secara semantik. Jika dihilangkan, server secara otomatis memilih percobaan OCR, Liveness, Pencocokan Wajah, POA, Phone, Email, AML, Validasi Database, dan Kuesioner yang ada yang statusnya `Declined`, `In Review`, `Not Finished`, atau `Expired` (percobaan NFC, analisis IP, estimasi usia, pencarian wajah, dan dokumen KYB tidak pernah dipilih secara otomatis; percobaan wajah non-face-match dipilih sebagai `LIVENESS`) — fitur yang tidak pernah dicoba oleh pengguna (tidak ada rekaman percobaan) TIDAK dipilih, sehingga sesi dengan nol percobaan mengembalikan `400` (\"No features found that need resubmission\") meskipun tidak ada yang disetujui; teruskan `nodes_to_resubmit` secara eksplisit dalam kasus tersebut. Langkah-langkah dieksekusi dalam urutan graf alur kerja terlepas dari urutan pengirimannya. `KYB_REGISTRY`, `KYB_KEY_PEOPLE`, dan alias `KYB` ditolak dengan `400` — pemeriksaan induk tersebut dihitung ulang dari sesi KYC anak mereka.",
                    "items": {
                      "type": "object",
                      "required": [
                        "node_id",
                        "feature"
                      ],
                      "properties": {
                        "node_id": {
                          "type": "string",
                          "description": "Pengenal node seperti yang muncul dalam definisi alur kerja sesi (misalnya `feature_ocr`, `feature_liveness`).",
                          "example": "feature_ocr"
                        },
                        "feature": {
                          "type": "string",
                          "description": "Tipe fitur dari node. Alias `ID_VERIFICATION`, `POA`, `PHONE`, dan `EMAIL` dinormalisasi di sisi server menjadi `OCR`, `PROOF_OF_ADDRESS`, `PHONE_VERIFICATION`, dan `EMAIL_VERIFICATION`. `KYB_REGISTRY`, `KYB_KEY_PEOPLE`, dan `KYB` lolos validasi skema tetapi selalu ditolak dengan aturan bisnis `400` yang ditunjukkan pada contoh.",
                          "enum": [
                            "OCR",
                            "OCR_BACK",
                            "NFC",
                            "AML",
                            "FACE",
                            "LIVENESS",
                            "FACE_MATCH",
                            "IP_ANALYSIS",
                            "AGE_ESTIMATION",
                            "PROOF_OF_ADDRESS",
                            "PHONE_VERIFICATION",
                            "EMAIL_VERIFICATION",
                            "FACE_SEARCH",
                            "DATABASE_VALIDATION",
                            "QUESTIONNAIRE",
                            "DOCUMENT_AI",
                            "KYB_DOCUMENTS",
                            "ID_VERIFICATION",
                            "POA",
                            "PHONE",
                            "EMAIL",
                            "KYB_REGISTRY",
                            "KYB_KEY_PEOPLE",
                            "KYB",
                            "GEOLOCATION"
                          ],
                          "example": "OCR"
                        }
                      }
                    }
                  },
                  "send_email": {
                    "type": "boolean",
                    "description": "Menentukan apakah akan mengirim email kepada pengguna mengenai perubahan tersebut. Memerlukan `email_address`. Untuk `Approved`/`Declined`, pengguna menerima pemberitahuan status; untuk `Resubmitted`, email menyertakan tautan verifikasi dan alasan pengiriman ulang per langkah.",
                    "default": false,
                    "example": false
                  },
                  "email_address": {
                    "type": "string",
                    "format": "email",
                    "description": "Penerima untuk email notifikasi. **Wajib diisi jika `send_email` bernilai `true`** — mengabaikannya akan mengembalikan `400`.",
                    "example": "user@example.com"
                  },
                  "email_language": {
                    "type": "string",
                    "description": "Bahasa untuk email notifikasi. Menerima string apa pun pada tingkat skema; kode yang tidak didukung akan beralih ke bahasa Inggris (`en`) secara senyap.",
                    "default": "en",
                    "example": "en"
                  },
                  "email_preview_token": {
                    "type": "string",
                    "writeOnly": true,
                    "minLength": 1,
                    "maxLength": 512,
                    "description": "Tanda terima opsional dari [Preview Decision Email](/id/sessions-api/preview-decision-email) (untuk `Approved` dan `Declined`) atau [Preview Resubmission Email](/id/sessions-api/preview-resubmission) (untuk `Resubmitted`): berupa `preview_token`-nya. Hanya valid dengan `send_email: true`; tanpanya, permintaan menghasilkan respons `400`. Penerima, bahasa, status sesi, pengirim, dan email (serta, untuk pengiriman ulang, langkah-langkah yang dipilih) harus tetap cocok dengan pratinjau, dan tanda terima kedaluwarsa setelah 15 menit. Jika tidak, permintaan menghasilkan respons `409` sebelum sesi berubah atau email dikirim. Integrasi yang sudah ada dapat mengabaikan kolom ini."
                  }
                }
              },
              "examples": {
                "Approve Session": {
                  "summary": "Setujui sesi setelah peninjauan manual",
                  "value": {
                    "new_status": "Approved",
                    "comment": "All checks passed manual review"
                  }
                },
                "Decline Session": {
                  "summary": "Tolak sesi",
                  "value": {
                    "new_status": "Declined",
                    "comment": "Suspected fraud"
                  }
                },
                "Resubmit Specific Steps": {
                  "summary": "Minta pengiriman ulang langkah yang dipilih, dengan email",
                  "value": {
                    "new_status": "Resubmitted",
                    "nodes_to_resubmit": [
                      {
                        "node_id": "feature_ocr",
                        "feature": "OCR"
                      },
                      {
                        "node_id": "feature_liveness",
                        "feature": "LIVENESS"
                      }
                    ],
                    "send_email": true,
                    "email_address": "user@example.com",
                    "email_language": "en"
                  }
                },
                "Resubmit Auto-select": {
                  "summary": "Minta pengiriman ulang (pilih otomatis langkah yang tidak disetujui)",
                  "value": {
                    "new_status": "Resubmitted"
                  }
                },
                "Approve With Previewed Email": {
                  "summary": "Setujui dan kirim email yang dikembalikan oleh Preview Decision Email",
                  "value": {
                    "new_status": "Approved",
                    "send_email": true,
                    "email_address": "person@example.com",
                    "email_language": "en",
                    "email_preview_token": "eyJkaWdlc3QiOiI0ZjJhIn0:1uExAm:Pl3x4mpleS1gnatureValue000000000000000"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Status diperbarui. Respons hanya berisi `session_id`; ambil sesi yang diperbarui melalui [Get Decision](#get-/v3/session/-sessionId-/decision/). Webhook `status.updated` akan terpicu setelah perubahan diterapkan. Mengulangi `Approved` atau `Declined` mengembalikan isi respons yang sama dan tidak mengubah apa pun.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "session_id": {
                      "type": "string",
                      "format": "uuid",
                      "description": "UUID sesi yang diperbarui."
                    }
                  }
                },
                "examples": {
                  "Updated": {
                    "summary": "Dikembalikan baik untuk Approved, Declined, maupun Resubmitted",
                    "value": {
                      "session_id": "3472fb7c-8f7c-4d1a-9cf4-cf3d74ce1a60"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Kesalahan validasi. Kesalahan kolom diterima sebagai `{\"<field>\": [\"<message>\"]}` (beberapa penolakan aturan bisnis menggunakan nilai string sebagai gantinya: `{\"nodes_to_resubmit\": \"<message>\"}`), kesalahan lintas status sebagai `{\"detail\": \"<message>\"}`, dan kesalahan status yang sama sebagai larik JSON biasa.",
            "content": {
              "application/json": {
                "examples": {
                  "Wrong Current Status": {
                    "summary": "Sesi tidak berada dalam status yang dapat diperbarui",
                    "value": {
                      "detail": "Only sessions with status Approved, Declined, In Review, Kyc Expired, Abandoned, Resubmitted can be updated. Current status: In Progress"
                    }
                  },
                  "Invalid Status Value": {
                    "summary": "new_status adalah status sesi nyata tetapi bukan salah satu dari Approved/Declined/Resubmitted",
                    "value": {
                      "new_status": [
                        "You can only update the status to 'Approved', 'Declined', or 'Resubmitted'."
                      ]
                    }
                  },
                  "Missing new_status": {
                    "summary": "Kolom wajib tidak disertakan",
                    "value": {
                      "new_status": [
                        "This field is required."
                      ]
                    }
                  },
                  "Same Status": {
                    "summary": "Kirim ulang diminta pada sesi yang sudah Dikirim ulang",
                    "value": [
                      "The new status is the same as the current status."
                    ]
                  },
                  "Email Address Required": {
                    "summary": "send_email bernilai true tanpa email_address",
                    "value": {
                      "email_address": [
                        "Email address is required when send_email is true."
                      ]
                    }
                  },
                  "Non-resubmittable Feature": {
                    "summary": "Kirim ulang menargetkan pemeriksaan induk KYB",
                    "value": {
                      "nodes_to_resubmit": "The following features cannot be resubmitted directly: KYB_REGISTRY. Resubmit the relevant child KYC sessions instead; the parent will recompute automatically."
                    }
                  },
                  "Nothing To Resubmit": {
                    "summary": "Pilihan otomatis tidak menemukan fitur yang belum disetujui",
                    "value": {
                      "nodes_to_resubmit": "No features found that need resubmission. All features are already approved."
                    }
                  },
                  "Invalid Feature Choice": {
                    "summary": "Fitur tidak dikenal di nodes_to_resubmit",
                    "value": {
                      "nodes_to_resubmit": [
                        {
                          "feature": [
                            "\"BOGUS\" is not a valid choice. Valid choices are: OCR, OCR_BACK, NFC, AML, FACE, LIVENESS, FACE_MATCH, IP_ANALYSIS, AGE_ESTIMATION, PROOF_OF_ADDRESS, PHONE_VERIFICATION, EMAIL_VERIFICATION, FACE_SEARCH, DATABASE_VALIDATION, QUESTIONNAIRE, KYB_REGISTRY, KYB_DOCUMENTS, KYB_KEY_PEOPLE, ID_VERIFICATION, POA, PHONE, EMAIL, KYB"
                          ]
                        }
                      ]
                    }
                  },
                  "Invalid Status Value (not a status at all)": {
                    "summary": "new_status bukan nilai StatusChoices yang valid",
                    "value": {
                      "new_status": [
                        "\"Bogus\" is not a valid choice."
                      ]
                    }
                  },
                  "Preview Receipt Without Email": {
                    "summary": "email_preview_token dikirim tanpa send_email: true",
                    "value": {
                      "email_preview_token": [
                        "A preview receipt is only valid when the email is sent."
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Kunci API dengan cakupan terbatas telah kedaluwarsa.",
            "content": {
              "application/json": {
                "examples": {
                  "Expired API Key": {
                    "summary": "Kunci API ber-scope melewati tanggal kedaluwarsanya",
                    "value": {
                      "detail": "This API key has expired."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Kredensial tidak ada atau izin tidak mencukupi, atau `session_id` milik aplikasi lain.",
            "content": {
              "application/json": {
                "examples": {
                  "Invalid Credentials": {
                    "summary": "x-api-key tidak ada atau tidak valid",
                    "value": {
                      "detail": "Authentication credentials were not provided or are invalid."
                    }
                  },
                  "Missing Privilege": {
                    "summary": "Kunci API tidak memiliki write:sessions",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Tidak ada sesi KYC atau KYB dengan `session_id` ini (sesi yang dihapus juga mengembalikan `404`).",
            "content": {
              "application/json": {
                "examples": {
                  "Not Found": {
                    "summary": "session_id tidak dikenal",
                    "value": {
                      "detail": "Not found."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Pengiriman ulang yang hanya menargetkan fitur khusus backend (AML, DATABASE_VALIDATION, IP_ANALYSIS) diulangi dalam jendela cooldown 30 detik; pengulangan langsung tidak dapat mengubah hasilnya. Tunggu dan coba lagi setelah interval yang ditunjukkan dalam `Retry-After`.",
            "content": {
              "application/json": {
                "examples": {
                  "Backend-only resubmit throttled": {
                    "value": {
                      "detail": "This session was already resubmitted for backend-only features within the last 30 seconds; repeating it cannot change the outcome. Wait before resubmitting again."
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "Pratinjau email telah berubah atau kedaluwarsa. Buat pratinjau baru sebelum mengonfirmasi; tidak ada perubahan sesi atau pengiriman email yang terjadi.",
            "content": {
              "application/json": {
                "examples": {
                  "Preview Changed": {
                    "summary": "Tanda terima tidak lagi cocok, atau lebih lama dari 15 menit",
                    "value": {
                      "detail": "This email preview changed or expired. Preview the message again before confirming."
                    }
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X PATCH \\\n  https://verification.didit.me/v3/session/11111111-2222-3333-4444-555555555555/update-status/ \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"new_status\": \"Approved\",\n    \"comment\": \"All checks passed manual review\"\n  }'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.update_status(\n    \"11111111-2222-3333-4444-555555555555\",\n    new_status=\"Approved\",\n    comment=\"All checks passed manual review\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.updateStatus(\"11111111-2222-3333-4444-555555555555\", {\n  new_status: \"Approved\",\n  comment: \"All checks passed manual review\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.UpdateStatus(ctx, \"11111111-2222-3333-4444-555555555555\", didit.SessionsUpdateStatusParams{\n\tNewStatus: \"Approved\",\n\tComment:   didit.String(\"All checks passed manual review\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.SessionsUpdateStatusParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().updateStatus(\"11111111-2222-3333-4444-555555555555\", SessionsUpdateStatusParams.builder()\n        .newStatus(SessionsUpdateStatusParams.NewStatus.of(\"Approved\"))\n        .comment(\"All checks passed manual review\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->sessions->updateStatus('11111111-2222-3333-4444-555555555555', [\n    'new_status' => 'Approved',\n    'comment' => 'All checks passed manual review',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.update_status(\n  \"11111111-2222-3333-4444-555555555555\",\n  new_status: \"Approved\",\n  comment: \"All checks passed manual review\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.UpdateStatusAsync(\"11111111-2222-3333-4444-555555555555\", new SessionsUpdateStatusParams\n{\n    NewStatus = \"Approved\",\n    Comment = \"All checks passed manual review\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/id-verification/": {
      "post": {
        "summary": "Verifikasi Identitas (OCR dokumen + pemeriksaan penipuan)",
        "description": "Lakukan OCR pada dokumen identitas dan jalankan pemeriksaan penipuan dokumen dalam satu panggilan — mengembalikan kolom pemegang dokumen yang diekstrak, MRZ yang diurai, `status` `Approved`/`Declined`/`In Review`, serta daftar `warnings` yang menjelaskan setiap masalah yang ditemukan. Mendukung 14,000+ jenis dokumen dari 220+ negara dan wilayah.\n\n**Cara kerjanya.** Kirimkan `front_image` dokumen (wajib) dan, untuk dokumen dua sisi, `back_image`. Unggah foto yang tidak dipotong dengan keempat sudut dokumen terlihat — layanan mendeteksi, menyelaraskan, dan memotong dokumen secara mandiri, jadi jangan memotongnya terlebih dahulu. Dokumen diklasifikasikan secara otomatis (Anda tidak perlu menyatakan negara atau jenis dokumen), zona visual dibaca dengan OCR, serta MRZ dan kode batang apa pun didekode. Pemeriksaan silang kemudian memvalidasi tanggal, format angka, dan digit pemeriksa MRZ, serta membandingkan zona visual dengan MRZ. Dengan `perform_document_liveness=true`, gambar juga diskrining terhadap pemutaran ulang layar, salinan cetak, dan manipulasi potret.\n\n**Logika keputusan.** `status` adalah `Approved` kecuali jika setidaknya satu peringatan menghasilkan penolakan. Risiko penipuan dan kegagalan fatal selalu menolak: `DOCUMENT_EXPIRED`, `SCREEN_CAPTURE_DETECTED`, `PRINTED_COPY_DETECTED`, `PORTRAIT_MANIPULATION_DETECTED`, `PUBLIC_DOCUMENT_IMAGE_DETECTED`, ditambah kegagalan ekstraksi (`NAME_NOT_DETECTED`, `DATE_OF_BIRTH_NOT_DETECTED`, `DOCUMENT_NUMBER_NOT_DETECTED`). (`PORTRAIT_IMAGE_NOT_DETECTED`, `INVALID_DATE`, dan `MRZ_NOT_DETECTED` ada di dalam sesi alur kerja tetapi tidak pernah dihasilkan oleh endpoint mandiri ini. `COULD_NOT_DETECT_DOCUMENT_TYPE` dikembalikan di sini ketika gambar depan tidak cocok dengan desain dokumen resmi yang diketahui dengan keyakinan tinggi, dan menolak permintaan tersebut.) Tiga kelompok risiko dapat dikonfigurasi per permintaan melalui `invalid_mrz_action`, `inconsistent_data_action`, dan `expiration_date_not_detected_action` (`DECLINE` atau `NO_ACTION`). Semua peringatan lainnya (misalnya `POSSIBLE_DUPLICATED_USER`) bersifat informasional dan tidak pernah menolak dengan sendirinya. Ketika `perform_document_liveness=true` (secara bawaan) dan pemeriksaan pemalsuan tidak menghasilkan skor yang dapat digunakan — penyedia gagal, merespons non-200, atau merespons HTTP 200 dengan `status=\"ERR\"` - panggilan mengembalikan `200` dengan `status: \"In Review\"` dan peringatan `DOCUMENT_LIVENESS_NOT_COMPUTED` (`log_type: \"warning\"`) alih-alih `Approved`: pemeriksaan yang tidak berjalan bukanlah bukti bahwa dokumen tersebut asli. Eskalasi ini tidak dapat dikonfigurasi dan tidak pernah menggantikan `Declined`; dengan `perform_document_liveness=false`, pemeriksaan dilewati dan status mengikuti sisa peringatan seperti sebelumnya. Dokumen yang tidak dapat diproses sama sekali mengembalikan `400` dengan `{\"error\": \"COULD_NOT_RECOGNIZE_DOCUMENT\"}`; dokumen yang dapat dibaca tetapi bermasalah mengembalikan `200` dengan `status: \"Declined\"` — selalu periksa `id_verification.status` dan `id_verification.warnings`, bukan hanya kode HTTP.\n\n**Penagihan.** Setiap respons `200` menggunakan satu kredit API Verifikasi Identitas (dibayar dari kredit paket atau saldo isi ulang Anda). Ketika saldo organisasi tidak dapat mencukupi panggilan, endpoint mengembalikan `403` dengan kesalahan tidak cukup kredit sebelum pemrosesan gambar apa pun.\n\n**Persistensi sesi (`save_api_request`, secara bawaan `true`).** Ketika `true`, panggilan disimpan secara persisten sebagai sesi bertipe API: sesi muncul di Business Console, `request_id` yang dikembalikan adalah ID sesi nyata yang dapat Anda teruskan ke `GET /v3/session/{sessionId}/decision/`, gambar dokumen/potret yang telah dipotong disimpan dan dikembalikan sebagai URL media sementara (`https://<media-host>/ocr/...`), dan webhook `status.updated` dipancarkan ke endpoint webhook yang Anda konfigurasi. Ketika `false`, tidak ada yang disimpan, `request_id` adalah UUID korelasi satu kali, dan `portrait_image`/`front_image`/`back_image` dikembalikan secara langsung sebagai string JPEG yang dienkode base64.\n\n**Sandbox.** Kunci API sandbox melewati semua pemrosesan dan penagihan: setelah validasi permintaan (input yang salah format tetap mengembalikan `400`), endpoint mengembalikan payload tiruan `Approved` statis (kartu identitas AS \"Sandbox User\" fiktif), tidak ada sesi yang disimpan secara persisten, dan tidak ada kredit yang digunakan.\n\n**Autentikasi.** Kirim kunci API aplikasi Anda di header `x-api-key`. Kredensial yang hilang atau tidak valid mengembalikan `403` (`{\"detail\": \"You do not have permission to perform this action.\"}`) — API ini tidak pernah mengembalikan `401`.\n\n**Batas laju.** Anggaran tulis bersama sebesar 300 permintaan/menit per kunci API di seluruh endpoint POST/PATCH/DELETE; melampauinya akan mengembalikan `429`.",
        "operationId": "post_v3id-verification",
        "x-didit-sdk": {
          "resource": "id_verification",
          "method": "verify",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Standalone APIs"
        ],
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "required": [
                  "front_image"
                ],
                "properties": {
                  "front_image": {
                    "type": "string",
                    "format": "binary",
                    "description": "Sisi depan dokumen identitas. Ekstensi yang diizinkan: `tiff`, `jpg`, `jpeg`, `png`, `webp`, `pdf`. Ukuran unggahan maksimum: **10 MB** (file yang lebih besar ditolak dengan `400`). Dokumen PDF dirender menjadi gambar sebelum proses OCR; PDF terenkripsi memerlukan `front_image_password`. Gambar otomatis dikompresi menjadi ~0.5 MB dan orientasi EXIF diterapkan. Unggah hasil pengambilan penuh yang tidak dipotong dengan keempat sudut dokumen terlihat jelas."
                  },
                  "front_image_password": {
                    "type": "string",
                    "description": "Kata sandi untuk mendekripsi `front_image` jika berupa PDF terenkripsi. Mengirimkan PDF terenkripsi tanpa kata sandi (atau dengan kata sandi yang salah) mengembalikan `400`.",
                    "writeOnly": true
                  },
                  "back_image": {
                    "type": "string",
                    "format": "binary",
                    "description": "Sisi belakang dokumen — kirimkan setiap kali dokumen memilikinya (banyak kartu identitas memiliki MRZ atau barcode di bagian belakang; mengabaikannya hanya akan mengosongkan MRZ dan kolom sisi belakang dalam respons — endpoint ini tidak memunculkan peringatan MRZ yang hilang). Batas format dan ukuran sama dengan `front_image`. Jika diabaikan, `back_image` dan kolom sisi belakang bernilai `null` dalam respons."
                  },
                  "back_image_password": {
                    "type": "string",
                    "description": "Kata sandi untuk mendekripsi `back_image` jika berupa PDF terenkripsi.",
                    "writeOnly": true
                  },
                  "perform_document_liveness": {
                    "type": "boolean",
                    "default": true,
                    "description": "Memeriksa kedua gambar untuk serangan presentasi: pemutaran ulang layar (`SCREEN_CAPTURE_DETECTED`), salinan cetak (`PRINTED_COPY_DETECTED`), dan manipulasi potret (`PORTRAIT_MANIPULATION_DETECTED`). Salah satu dari kondisi ini akan menyebabkan penolakan otomatis. Diaktifkan secara default; atur ke `false` untuk melewati skrining penipuan dan mengurangi latensi. Ketika diaktifkan dan penyedia tidak mengembalikan skor yang dapat digunakan, responsnya adalah `In Review` dengan peringatan `DOCUMENT_LIVENESS_NOT_COMPUTED` alih-alih `Approved`.",
                    "example": true
                  },
                  "minimum_age": {
                    "type": "integer",
                    "nullable": true,
                    "default": null,
                    "minimum": 1,
                    "maximum": 120,
                    "description": "Diterima dan divalidasi (1–120) tetapi **saat ini tidak diterapkan** oleh endpoint ini — kolom ini tidak pernah menghasilkan peringatan `MINIMUM_AGE_NOT_MET`. Terapkan aturan usia dari `date_of_birth`/`age` yang dikembalikan, atau gunakan alur kerja sesi verifikasi dengan pembatasan usia."
                  },
                  "expiration_date_not_detected_action": {
                    "type": "string",
                    "enum": [
                      "NO_ACTION",
                      "DECLINE"
                    ],
                    "default": "NO_ACTION",
                    "description": "Tindakan yang diambil saat tanggal kedaluwarsa tidak dapat dibaca (`EXPIRATION_DATE_NOT_DETECTED`). Default `NO_ACTION` karena banyak dokumen identitas tidak mencantumkan tanggal kedaluwarsa. Catatan: tanggal kedaluwarsa yang *terdeteksi dan telah lewat* selalu ditolak (`DOCUMENT_EXPIRED`), terlepas dari opsi ini."
                  },
                  "invalid_mrz_action": {
                    "type": "string",
                    "enum": [
                      "NO_ACTION",
                      "DECLINE"
                    ],
                    "default": "DECLINE",
                    "description": "Tindakan yang harus diambil ketika MRZ yang diekstrak gagal dalam validasi check-digit (`MRZ_VALIDATION_FAILED`). MRZ yang hilang tidak memunculkan peringatan pada endpoint ini. Hanya relevan untuk dokumen yang memiliki MRZ. `REVIEW` tidak didukung pada endpoint ini dan mengembalikan `400`."
                  },
                  "inconsistent_data_action": {
                    "type": "string",
                    "enum": [
                      "NO_ACTION",
                      "DECLINE"
                    ],
                    "default": "DECLINE",
                    "description": "Tindakan yang diambil saat data yang diekstraksi tidak konsisten secara internal: `DATA_INCONSISTENT`, `MRZ_AND_DATA_EXTRACTED_FROM_OCR_NOT_SAME` (zona visual tidak sesuai dengan MRZ), atau `DOCUMENT_NAME_DIFFERENT_FROM_OTHER_APPROVED_DOCUMENTS`."
                  },
                  "critical_field_occlusion_action": {
                    "type": "string",
                    "enum": [
                      "NO_ACTION",
                      "DECLINE"
                    ],
                    "default": "DECLINE",
                    "description": "Tindakan yang diambil saat kolom tercetak yang penting tertutup secara fisik pada hasil pengambilan gambar (`CRITICAL_FIELD_OCCLUSION_DETECTED`) - nomor identitas, nama, tanggal lahir, atau tanggal kedaluwarsa. Ditolak secara default, sama seperti risiko integritas dokumen lainnya pada endpoint ini: menutupi nomor yang menjadi acuan rekonsiliasi laporan merupakan bentuk dokumen yang disunting. Nilai yang terbaca untuk kolom yang tertutup akan tetap dihapus dari ekstraksi, sehingga peringatan `*_NOT_DETECTED` yang sesuai biasanya menyertainya. `REVIEW` tidak didukung pada endpoint ini dan mengembalikan `400`."
                  },
                  "document_or_personal_number_format_mismatch_action": {
                    "type": "string",
                    "enum": [
                      "NO_ACTION",
                      "DECLINE"
                    ],
                    "default": "NO_ACTION",
                    "description": "Tindakan yang diambil saat nomor tidak cocok dengan format yang digunakan oleh otoritas penerbit untuk jenis dokumen tersebut (`DOCUMENT_NUMBER_FORMAT_MISMATCH`, `PERSONAL_NUMBER_FORMAT_MISMATCH`). Default `NO_ACTION`, yang melaporkan peringatan tanpa mengubah status. `REVIEW` tidak didukung pada endpoint ini dan mengembalikan `400`."
                  },
                  "preferred_characters": {
                    "type": "string",
                    "enum": [
                      "latin",
                      "non_latin"
                    ],
                    "default": "latin",
                    "description": "Aksara pilihan untuk kolom nama/alamat pada dokumen yang mencetak teks Latin dan non-Latin (Arab, Sirilik, CJK, …). `latin` mengembalikan nilai yang ditransliterasikan/Latin; `non_latin` memprioritaskan aksara asli."
                  },
                  "save_api_request": {
                    "type": "boolean",
                    "default": true,
                    "description": "Jika `true` (default), menyimpan panggilan sebagai sesi tipe API — terlihat di Business Console, dapat diambil melalui `GET /v3/session/{sessionId}/decision/` menggunakan `request_id` yang dikembalikan, diumumkan melalui webhook `status.updated`, dan dengan gambar dokumen dikembalikan sebagai URL media. Jika `false`, tidak ada yang disimpan, `request_id` adalah UUID sementara, dan gambar dikembalikan secara inline sebagai string base64 JPEG.",
                    "example": true
                  },
                  "vendor_data": {
                    "type": "string",
                    "description": "String buram opsional (ID pengguna internal, email, UUID Anda…) yang disimpan pada sesi yang dipertahankan dan dikembalikan dalam respons. Gunakan untuk mengorelasikan panggilan API dengan catatan Anda sendiri dan memfilter sesi nantinya.",
                    "example": "user-123"
                  },
                  "metadata": {
                    "type": "object",
                    "additionalProperties": true,
                    "description": "Objek JSON opsional yang disimpan bersama sesi (saat `save_api_request=true`) dan dikembalikan dalam respons. Dalam permintaan multipart, kirimkan sebagai kolom string yang dikodekan dalam JSON (misalnya `metadata={\"flow\":\"onboarding\"}`) — kolom ini akan diuraikan menjadi sebuah objek.",
                    "example": {
                      "flow": "onboarding"
                    }
                  }
                }
              },
              "example": {
                "front_image": "(binary JPEG/PNG/PDF of the document front)",
                "back_image": "(binary JPEG/PNG/PDF of the document back)",
                "perform_document_liveness": true,
                "save_api_request": true,
                "vendor_data": "user-123",
                "metadata": {
                  "flow": "onboarding"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Dokumen diproses. `id_verification.status` bernilai `Approved`, `Declined`, atau `In Review`; setiap masalah yang terdeteksi dirinci dalam `id_verification.warnings`. `In Review` dikembalikan saat pemeriksaan liveness dokumen yang diminta tidak menghasilkan hasil yang dapat digunakan (`DOCUMENT_LIVENESS_NOT_COMPUTED`). Dokumen yang bermasalah tetap menghasilkan `200` dengan `status: \"Declined\"` — periksa isi respons, bukan hanya kode HTTP. Ketika `save_api_request=true`, `request_id` adalah id sesi yang disimpan dan kolom gambar berupa URL media berumur pendek; jika `save_api_request=false`, kolom tersebut berupa string JPEG base64 inline.",
            "content": {
              "application/json": {
                "examples": {
                  "Approved": {
                    "summary": "Kartu identitas dua sisi terbaca dengan jelas (disimpan — gambar sebagai URL media)",
                    "value": {
                      "request_id": "11d219ed-d59c-4b1d-8d65-9b933f12d5b8",
                      "id_verification": {
                        "status": "Approved",
                        "document_type": "Identity Card",
                        "document_subtype": "ID_CARD_GENERIC",
                        "document_number": "CBX164224",
                        "personal_number": "20446581H",
                        "portrait_image": "https://<media-host>/ocr/11d219ed-d59c-4b1d-8d65-9b933f12d5b8-portrait_image-8c2f.jpg?signature=...",
                        "front_image": "https://<media-host>/ocr/11d219ed-d59c-4b1d-8d65-9b933f12d5b8-front_image-4a1e.jpg?signature=...",
                        "back_image": "https://<media-host>/ocr/11d219ed-d59c-4b1d-8d65-9b933f12d5b8-back_image-77b0.jpg?signature=...",
                        "front_image_camera_front": null,
                        "back_image_camera_front": null,
                        "front_image_camera_front_face_match_score": null,
                        "back_image_camera_front_face_match_score": null,
                        "front_image_quality_score": {
                          "focus_score": 78.0,
                          "brightness_score": 83.2,
                          "brightness_issue": "ok",
                          "is_document_fully_visible": true,
                          "resolution_score": 40.7,
                          "overall_score": 70.2
                        },
                        "back_image_quality_score": {
                          "focus_score": 100.0,
                          "brightness_score": 95.6,
                          "brightness_issue": "ok",
                          "is_document_fully_visible": true,
                          "resolution_score": 43.0,
                          "overall_score": 84.4
                        },
                        "date_of_birth": "1980-01-13",
                        "age": 46,
                        "expiration_date": "2032-03-31",
                        "date_of_issue": "2022-03-31",
                        "issuing_state": "ESP",
                        "issuing_state_name": "Spain",
                        "first_name": "Julio Francisco",
                        "last_name": "Fores Sena",
                        "full_name": "Julio Francisco Fores Sena",
                        "gender": "M",
                        "address": "Brda. Urb. El Cardonal 0052 52 Po3 B,Taco,San Cristobal De La Laguna,Santa Cruz De Tenerife",
                        "formatted_address": "Av. el Cardonal, 52, b, 38108 La Laguna, Santa Cruz de Tenerife, Spain",
                        "place_of_birth": "Valencia, Valencia",
                        "marital_status": "UNKNOWN",
                        "nationality": "ESP",
                        "extra_fields": {
                          "first_surname": "Fores",
                          "second_surname": "Sena"
                        },
                        "mrz": {
                          "surname": "FORES SENA",
                          "name": "JULIO FRANCISCO",
                          "country": "ESP",
                          "nationality": "ESP",
                          "birth_date": "800113",
                          "expiry_date": "320331",
                          "sex": "M",
                          "document_type": "ID",
                          "document_number": "CBX164224",
                          "optional_data": "20446581H",
                          "optional_data_2": "",
                          "birth_date_hash": "9",
                          "expiry_date_hash": "8",
                          "document_number_hash": "3",
                          "final_hash": "3",
                          "personal_number": "20446581H",
                          "warnings": [],
                          "errors": [],
                          "mrz_type": "TD1",
                          "mrz_string": "IDESPCBX164224320446581H<<<<<<\n8001139M3203318ESP<<<<<<<<<<<3\nFORES<SENA<<JULIO<FRANCISCO<<<",
                          "mrz_key": "CBX164224380011393203318"
                        },
                        "parsed_address": {
                          "street_1": "Avenida el Cardonal 52",
                          "street_2": "b",
                          "city": "La Laguna",
                          "region": "Canarias",
                          "country": "ES",
                          "postal_code": "38108",
                          "address_type": "Avenida",
                          "formatted_address": "Av. el Cardonal, 52, b, 38108 La Laguna, Santa Cruz de Tenerife, Spain",
                          "raw_results": {
                            "address_components": [
                              {
                                "long_name": "b",
                                "short_name": "b",
                                "types": [
                                  "subpremise"
                                ]
                              },
                              {
                                "long_name": "52",
                                "short_name": "52",
                                "types": [
                                  "street_number"
                                ]
                              },
                              {
                                "long_name": "Avenida el Cardonal",
                                "short_name": "Av. el Cardonal",
                                "types": [
                                  "route"
                                ]
                              },
                              {
                                "long_name": "La Laguna",
                                "short_name": "La Laguna",
                                "types": [
                                  "locality",
                                  "political"
                                ]
                              },
                              {
                                "long_name": "Spain",
                                "short_name": "ES",
                                "types": [
                                  "country",
                                  "political"
                                ]
                              },
                              {
                                "long_name": "38108",
                                "short_name": "38108",
                                "types": [
                                  "postal_code"
                                ]
                              }
                            ],
                            "formatted_address": "Av. el Cardonal, 52, b, 38108 La Laguna, Santa Cruz de Tenerife, Spain",
                            "geometry": {
                              "location": {
                                "lat": 28.4501161,
                                "lng": -16.3004407
                              },
                              "location_type": "ROOFTOP"
                            },
                            "types": [
                              "street_address",
                              "subpremise"
                            ]
                          },
                          "document_location": {
                            "latitude": 28.4501161,
                            "longitude": -16.3004407
                          },
                          "label": "Spain Identity Card Address",
                          "is_verified": true,
                          "category": "Residential"
                        },
                        "warnings": [],
                        "barcodes": []
                      },
                      "vendor_data": "user-123",
                      "metadata": {
                        "flow": "onboarding"
                      },
                      "created_at": "2026-06-12T02:21:56.013573+00:00"
                    }
                  },
                  "Declined - expired document": {
                    "summary": "Pengunggahan hanya sisi depan dari kartu identitas yang telah kedaluwarsa",
                    "value": {
                      "request_id": "f61681b8-9422-4378-ac3e-04c6a247fb45",
                      "id_verification": {
                        "status": "Declined",
                        "document_type": "Identity Card",
                        "document_subtype": "ID_CARD_GENERIC",
                        "document_number": "BNK123072",
                        "personal_number": "21771255F",
                        "portrait_image": "https://<media-host>/ocr/f61681b8-9422-4378-ac3e-04c6a247fb45-portrait_image-1d9a.jpg?signature=...",
                        "front_image": "https://<media-host>/ocr/f61681b8-9422-4378-ac3e-04c6a247fb45-front_image-5c2b.jpg?signature=...",
                        "back_image": null,
                        "front_image_camera_front": null,
                        "back_image_camera_front": null,
                        "front_image_camera_front_face_match_score": null,
                        "back_image_camera_front_face_match_score": null,
                        "front_image_quality_score": {
                          "focus_score": 100.0,
                          "brightness_score": 95.7,
                          "brightness_issue": "ok",
                          "is_document_fully_visible": true,
                          "resolution_score": 22.2,
                          "overall_score": 79.3
                        },
                        "back_image_quality_score": null,
                        "date_of_birth": "1997-01-30",
                        "age": 29,
                        "expiration_date": "2025-11-26",
                        "date_of_issue": null,
                        "issuing_state": "ESP",
                        "issuing_state_name": "Spain",
                        "first_name": "Lucia",
                        "last_name": "Marin Castro",
                        "full_name": "Lucia Marin Castro",
                        "gender": "F",
                        "address": null,
                        "formatted_address": null,
                        "place_of_birth": null,
                        "marital_status": "UNKNOWN",
                        "nationality": "ESP",
                        "extra_fields": {
                          "first_surname": "Marin",
                          "second_surname": "Castro"
                        },
                        "mrz": {},
                        "parsed_address": null,
                        "warnings": [
                          {
                            "risk": "DOCUMENT_EXPIRED",
                            "feature": "ID_VERIFICATION",
                            "additional_data": null,
                            "log_type": "error",
                            "short_description": "Document expired",
                            "long_description": "The document's expiration date has passed, rendering it no longer valid for use."
                          }
                        ],
                        "barcodes": []
                      },
                      "vendor_data": "user-123",
                      "metadata": null,
                      "created_at": "2026-06-12T02:25:48.117204+00:00"
                    }
                  }
                },
                "schema": {
                  "type": "object",
                  "properties": {
                    "request_id": {
                      "type": "string",
                      "format": "uuid",
                      "description": "ID sesi yang disimpan saat `save_api_request=true` (dapat digunakan dengan `GET /v3/session/{sessionId}/decision/`); jika tidak, berupa UUID korelasi sementara."
                    },
                    "id_verification": {
                      "type": "object",
                      "properties": {
                        "status": {
                          "type": "string",
                          "enum": [
                            "Approved",
                            "Declined",
                            "In Review"
                          ],
                          "description": "`Approved` saat tidak ada peringatan yang menghasilkan penolakan dan pemeriksaan liveness dokumen yang diminta menghasilkan hasil yang dapat digunakan; `In Review` saat pemeriksaan yang diminta tersebut tidak menghasilkan hasil yang dapat digunakan (`DOCUMENT_LIVENESS_NOT_COMPUTED`); `Declined` saat sebuah peringatan menghasilkan penolakan — daftar `warnings` menjelaskan alasannya."
                        },
                        "document_type": {
                          "type": "string",
                          "nullable": true,
                          "description": "Nama tampilan jenis dokumen yang terdeteksi: `Identity Card`, `Passport`, `Driver's License`, `Residence Permit`, `Health Insurance Card`, atau `Tax Card`. Bernilai `null` jika dokumen tidak dapat diklasifikasikan.",
                          "example": "Identity Card"
                        },
                        "document_subtype": {
                          "type": "string",
                          "nullable": true,
                          "description": "Subtipe yang lebih mendetail jika tersedia (mis. `ID_CARD_GENERIC`, `EPASSPORT`).",
                          "example": "ID_CARD_GENERIC"
                        },
                        "document_number": {
                          "type": "string",
                          "nullable": true,
                          "example": "CBX164224"
                        },
                        "personal_number": {
                          "type": "string",
                          "nullable": true,
                          "description": "Nomor pribadi/nasional sekunder yang tercetak pada beberapa dokumen.",
                          "example": "20446581H"
                        },
                        "portrait_image": {
                          "type": "string",
                          "nullable": true,
                          "description": "Foto potret yang dipotong dari dokumen. URL media berumur pendek (`https://<media-host>/ocr/...`) jika `save_api_request=true` (default); string JPEG yang dienkode base64 inline jika `save_api_request=false`. Bernilai `null` jika tidak ada potret yang terdeteksi."
                        },
                        "front_image": {
                          "type": "string",
                          "nullable": true,
                          "description": "Hasil crop yang disejajarkan dari bagian depan dokumen. URL media jika disimpan, inline base64 JPEG jika tidak."
                        },
                        "back_image": {
                          "type": "string",
                          "nullable": true,
                          "description": "Hasil crop yang disejajarkan dari bagian belakang dokumen. `null` jika tidak ada `back_image` yang diunggah."
                        },
                        "front_image_camera_front": {
                          "type": "string",
                          "nullable": true,
                          "description": "Selalu `null` pada endpoint ini (hanya diisi pada sesi verifikasi dengan pengambilan gambar melalui kamera)."
                        },
                        "back_image_camera_front": {
                          "type": "string",
                          "nullable": true,
                          "description": "Selalu `null` pada endpoint ini."
                        },
                        "front_image_camera_front_face_match_score": {
                          "type": "number",
                          "nullable": true,
                          "description": "Selalu `null` pada endpoint ini."
                        },
                        "back_image_camera_front_face_match_score": {
                          "type": "number",
                          "nullable": true,
                          "description": "Selalu `null` pada endpoint ini."
                        },
                        "front_image_quality_score": {
                          "type": "object",
                          "nullable": true,
                          "description": "Diagnostik kualitas pengambilan untuk gambar yang diunggah (`null` jika sisi dokumen tidak diberikan atau penilaian gagal). Semua skor adalah 0–100.",
                          "properties": {
                            "focus_score": {
                              "type": "number",
                              "format": "float",
                              "description": "Ketajaman potongan dokumen (semakin tinggi semakin tajam)."
                            },
                            "brightness_score": {
                              "type": "number",
                              "format": "float",
                              "description": "Kualitas paparan (makin tinggi makin baik)."
                            },
                            "brightness_issue": {
                              "type": "string",
                              "nullable": true,
                              "description": "`ok` saat pencahayaan baik, jika tidak maka berupa masalah yang terdeteksi (misalnya terlalu gelap / terlalu terang)."
                            },
                            "is_document_fully_visible": {
                              "type": "boolean",
                              "nullable": true,
                              "description": "Menentukan apakah keempat sudut dokumen berada di dalam bingkai."
                            },
                            "resolution_score": {
                              "type": "number",
                              "format": "float",
                              "description": "Resolusi efektif dari area dokumen."
                            },
                            "overall_score": {
                              "type": "number",
                              "format": "float",
                              "description": "Skor kualitas agregat."
                            }
                          }
                        },
                        "back_image_quality_score": {
                          "type": "object",
                          "nullable": true,
                          "description": "Diagnostik kualitas pengambilan untuk gambar yang diunggah (`null` jika sisi dokumen tidak diberikan atau penilaian gagal). Semua skor adalah 0–100.",
                          "properties": {
                            "focus_score": {
                              "type": "number",
                              "format": "float",
                              "description": "Ketajaman potongan dokumen (semakin tinggi semakin tajam)."
                            },
                            "brightness_score": {
                              "type": "number",
                              "format": "float",
                              "description": "Kualitas paparan (makin tinggi makin baik)."
                            },
                            "brightness_issue": {
                              "type": "string",
                              "nullable": true,
                              "description": "`ok` saat pencahayaan baik, jika tidak maka berupa masalah yang terdeteksi (misalnya terlalu gelap / terlalu terang)."
                            },
                            "is_document_fully_visible": {
                              "type": "boolean",
                              "nullable": true,
                              "description": "Menentukan apakah keempat sudut dokumen berada di dalam bingkai."
                            },
                            "resolution_score": {
                              "type": "number",
                              "format": "float",
                              "description": "Resolusi efektif dari area dokumen."
                            },
                            "overall_score": {
                              "type": "number",
                              "format": "float",
                              "description": "Skor kualitas agregat."
                            }
                          }
                        },
                        "date_of_birth": {
                          "type": "string",
                          "format": "date",
                          "nullable": true,
                          "example": "1980-01-13"
                        },
                        "age": {
                          "type": "integer",
                          "nullable": true,
                          "description": "Usia pemegang dalam tahun, dihitung dari `date_of_birth`.",
                          "example": 46
                        },
                        "expiration_date": {
                          "type": "string",
                          "format": "date",
                          "nullable": true,
                          "example": "2032-03-31"
                        },
                        "date_of_issue": {
                          "type": "string",
                          "format": "date",
                          "nullable": true,
                          "example": "2022-03-31"
                        },
                        "issuing_state": {
                          "type": "string",
                          "nullable": true,
                          "description": "Negara penerbit (ISO 3166-1 alpha-3).",
                          "example": "ESP"
                        },
                        "issuing_state_name": {
                          "type": "string",
                          "nullable": true,
                          "example": "Spain"
                        },
                        "first_name": {
                          "type": "string",
                          "nullable": true,
                          "example": "Julio Francisco"
                        },
                        "last_name": {
                          "type": "string",
                          "nullable": true,
                          "example": "Fores Sena"
                        },
                        "full_name": {
                          "type": "string",
                          "nullable": true,
                          "example": "Julio Francisco Fores Sena"
                        },
                        "gender": {
                          "type": "string",
                          "nullable": true,
                          "description": "`M`, `F`, atau `null` ketika tidak tercetak/terdeteksi.",
                          "example": "M"
                        },
                        "address": {
                          "type": "string",
                          "nullable": true,
                          "description": "Alamat persis seperti yang tertera pada dokumen."
                        },
                        "formatted_address": {
                          "type": "string",
                          "nullable": true,
                          "description": "Versi `address` yang dinormalisasi dan di-geocode."
                        },
                        "place_of_birth": {
                          "type": "string",
                          "nullable": true,
                          "example": "Valencia, Valencia"
                        },
                        "marital_status": {
                          "type": "string",
                          "nullable": true,
                          "description": "`UNKNOWN` kecuali jika dokumen mencantumkan status perkawinan.",
                          "example": "UNKNOWN"
                        },
                        "nationality": {
                          "type": "string",
                          "nullable": true,
                          "description": "Kewarganegaraan pemegang (ISO 3166-1 alpha-3).",
                          "example": "ESP"
                        },
                        "extra_fields": {
                          "type": "object",
                          "nullable": true,
                          "additionalProperties": true,
                          "description": "Tambahan khusus dokumen yang tidak memiliki kolom khusus (misalnya `first_surname`/`second_surname` pada KTP Spanyol, kelas SIM pada surat izin mengemudi)."
                        },
                        "mrz": {
                          "type": "object",
                          "description": "Zona terbaca mesin yang telah diurai. Berupa **objek kosong** (`{}`) jika dokumen tidak memiliki MRZ atau tidak dapat dibaca — periksa juga daftar `warnings` dalam kasus tersebut. Tanggal di dalam MRZ menggunakan format mentah `YYMMDD`.",
                          "properties": {
                            "surname": {
                              "type": "string",
                              "example": "FORES SENA"
                            },
                            "name": {
                              "type": "string",
                              "example": "JULIO FRANCISCO"
                            },
                            "country": {
                              "type": "string",
                              "description": "Negara penerbit (ISO 3166-1 alpha-3).",
                              "example": "ESP"
                            },
                            "nationality": {
                              "type": "string",
                              "description": "Kewarganegaraan pemegang (ISO 3166-1 alpha-3).",
                              "example": "ESP"
                            },
                            "birth_date": {
                              "type": "string",
                              "description": "Tanggal lahir MRZ mentah (`YYMMDD`).",
                              "example": "800113"
                            },
                            "expiry_date": {
                              "type": "string",
                              "description": "Tanggal kedaluwarsa MRZ mentah (`YYMMDD`).",
                              "example": "320331"
                            },
                            "sex": {
                              "type": "string",
                              "example": "M"
                            },
                            "document_type": {
                              "type": "string",
                              "description": "Kode jenis dokumen MRZ (misalnya `ID`, `P`).",
                              "example": "ID"
                            },
                            "document_number": {
                              "type": "string",
                              "example": "CBX164224"
                            },
                            "optional_data": {
                              "type": "string",
                              "nullable": true,
                              "example": "20446581H"
                            },
                            "optional_data_2": {
                              "type": "string",
                              "nullable": true,
                              "example": ""
                            },
                            "birth_date_hash": {
                              "type": "string",
                              "description": "Digit pemeriksa MRZ untuk tanggal lahir.",
                              "example": "9"
                            },
                            "expiry_date_hash": {
                              "type": "string",
                              "description": "Digit pemeriksa MRZ untuk tanggal kedaluwarsa.",
                              "example": "8"
                            },
                            "document_number_hash": {
                              "type": "string",
                              "description": "Digit pemeriksa MRZ untuk nomor dokumen.",
                              "example": "3"
                            },
                            "final_hash": {
                              "type": "string",
                              "description": "Digit pemeriksa MRZ komposit.",
                              "example": "3"
                            },
                            "personal_number": {
                              "type": "string",
                              "nullable": true,
                              "example": "20446581H"
                            },
                            "warnings": {
                              "type": "array",
                              "items": {
                                "type": "string"
                              },
                              "description": "Peringatan penguraian MRZ yang bersifat non-fatal."
                            },
                            "errors": {
                              "type": "array",
                              "items": {
                                "type": "string"
                              },
                              "description": "Kesalahan digit pemeriksa/parsing MRZ. Kesalahan yang tidak kosong akan muncul sebagai peringatan `MRZ_VALIDATION_FAILED`."
                            },
                            "mrz_type": {
                              "type": "string",
                              "description": "Tata letak MRZ: `TD1` (kartu identitas, 3 baris), `TD2`, atau `TD3` (paspor, 2 baris).",
                              "example": "TD1"
                            },
                            "mrz_string": {
                              "type": "string",
                              "description": "Teks MRZ mentah sebagaimana dibaca, baris dipisahkan oleh `\\n`."
                            },
                            "mrz_key": {
                              "type": "string",
                              "description": "Kunci komposit (nomor dokumen + digit pemeriksa) yang digunakan untuk pemeriksaan silang."
                            }
                          }
                        },
                        "parsed_address": {
                          "type": "object",
                          "nullable": true,
                          "description": "Rincian terstruktur dan telah diberi geocode dari `address`. `null` jika dokumen tidak memuat alamat atau alamat tidak dapat diurai.",
                          "properties": {
                            "street_1": {
                              "type": "string",
                              "nullable": true,
                              "example": "Avenida el Cardonal 52"
                            },
                            "street_2": {
                              "type": "string",
                              "nullable": true,
                              "example": "b"
                            },
                            "city": {
                              "type": "string",
                              "nullable": true,
                              "example": "La Laguna"
                            },
                            "region": {
                              "type": "string",
                              "nullable": true,
                              "example": "Canarias"
                            },
                            "country": {
                              "type": "string",
                              "nullable": true,
                              "description": "Kode negara ISO 3166-1 alpha-2.",
                              "example": "ES"
                            },
                            "postal_code": {
                              "type": "string",
                              "nullable": true,
                              "example": "38108"
                            },
                            "address_type": {
                              "type": "string",
                              "nullable": true,
                              "example": "Avenida"
                            },
                            "formatted_address": {
                              "type": "string",
                              "nullable": true,
                              "description": "String alamat hasil geocoding kanonis.",
                              "example": "Av. el Cardonal, 52, b, 38108 La Laguna, Santa Cruz de Tenerife, Spain"
                            },
                            "raw_results": {
                              "type": "object",
                              "additionalProperties": true,
                              "description": "Payload geocoding mentah (`address_components`, `geometry.location`, `place_id`, …) untuk pengguna tingkat lanjut."
                            },
                            "document_location": {
                              "type": "object",
                              "nullable": true,
                              "properties": {
                                "latitude": {
                                  "type": "number"
                                },
                                "longitude": {
                                  "type": "number"
                                }
                              },
                              "description": "Koordinat hasil geocoding dari alamat dokumen."
                            },
                            "label": {
                              "type": "string",
                              "nullable": true,
                              "description": "Kolom dokumen mana tempat alamat dibaca.",
                              "example": "Spain Identity Card Address"
                            },
                            "is_verified": {
                              "type": "boolean",
                              "description": "Menentukan apakah geocoding mengonfirmasi keberadaan alamat tersebut."
                            },
                            "category": {
                              "type": "string",
                              "nullable": true,
                              "description": "Kategori alamat (misalnya `Residential`, `Commercial`).",
                              "example": "Residential"
                            }
                          }
                        },
                        "warnings": {
                          "type": "array",
                          "description": "Kosong jika persetujuan bersih. Setiap entri menjelaskan satu risiko yang terdeteksi; entri dengan `log_type: \"error\"` menetapkan `status` ke `Declined`, dan `DOCUMENT_LIVENESS_NOT_COMPUTED` (`log_type: \"warning\"`) menetapkannya ke `In Review`.",
                          "items": {
                            "type": "object",
                            "properties": {
                              "risk": {
                                "type": "string",
                                "description": "Kode risiko yang dapat dibaca mesin. Risiko yang selalu ditolak: `DOCUMENT_EXPIRED`, `MINIMUM_AGE_NOT_MET`, `PORTRAIT_IMAGE_NOT_DETECTED`, `SCREEN_CAPTURE_DETECTED`, `PRINTED_COPY_DETECTED`, `PORTRAIT_MANIPULATION_DETECTED`, `PUBLIC_DOCUMENT_IMAGE_DETECTED`, `INVALID_DATE`, `COULD_NOT_RECOGNIZE_DOCUMENT` (hanya 400, tidak pernah menjadi peringatan), `DOCUMENT_NUMBER_NOT_DETECTED`, `COULD_NOT_DETECT_DOCUMENT_TYPE`, `NAME_NOT_DETECTED`, `DATE_OF_BIRTH_NOT_DETECTED`. Diatur oleh opsi permintaan: `MRZ_NOT_DETECTED` / `MRZ_VALIDATION_FAILED` (`invalid_mrz_action`), `DATA_INCONSISTENT` / `MRZ_AND_DATA_EXTRACTED_FROM_OCR_NOT_SAME` / `DOCUMENT_NAME_DIFFERENT_FROM_OTHER_APPROVED_DOCUMENTS` (`inconsistent_data_action`), `EXPIRATION_DATE_NOT_DETECTED` (`expiration_date_not_detected_action`). Risiko lainnya (mis. `POSSIBLE_DUPLICATED_USER`) bersifat informasional. `DOCUMENT_LIVENESS_NOT_COMPUTED` dimunculkan ketika `perform_document_liveness=true` tetapi pemeriksaan pemalsuan tidak menghasilkan skor yang dapat digunakan; ini menetapkan `status` ke `In Review`. `COULD_NOT_DETECT_DOCUMENT_TYPE` juga dikembalikan saat bagian depan dokumen tidak cocok dengan desain dokumen resmi yang dikenal dengan keyakinan tinggi, misalnya dokumen yang diedit atau dihasilkan komputer, atau desain yang belum didukung.",
                                "example": "DOCUMENT_EXPIRED"
                              },
                              "feature": {
                                "type": "string",
                                "enum": [
                                  "ID_VERIFICATION"
                                ],
                                "description": "Fitur yang memunculkan peringatan. Selalu `ID_VERIFICATION` pada endpoint ini."
                              },
                              "additional_data": {
                                "type": "object",
                                "nullable": true,
                                "additionalProperties": true,
                                "description": "Konteks tambahan untuk beberapa risiko (misalnya `POSSIBLE_DUPLICATED_USER` menyertakan `duplicated_session_id`); `null` untuk sebagian besar."
                              },
                              "log_type": {
                                "type": "string",
                                "enum": [
                                  "error",
                                  "warning",
                                  "information"
                                ],
                                "description": "Tingkat keparahan. Peringatan `error` mendorong `status` menjadi `Declined`; `warning` (hanya `DOCUMENT_LIVENESS_NOT_COMPUTED`, ketika pemeriksaan pemalsuan yang diminta tidak menghasilkan skor yang dapat digunakan) mendorong `status` menjadi `In Review`; entri `information` bersifat anjuran dan tidak pernah mengubah status."
                              },
                              "short_description": {
                                "type": "string",
                                "description": "Ringkasan satu baris yang dapat dibaca manusia tentang risiko."
                              },
                              "long_description": {
                                "type": "string",
                                "description": "Penjelasan risiko yang mudah dibaca manusia."
                              }
                            }
                          }
                        },
                        "barcodes": {
                          "type": "array",
                          "description": "Barcode yang didekodekan dari dokumen (PDF417, QR, …). Kosong jika dokumen tidak memilikinya atau tidak ada yang dapat dibaca.",
                          "items": {
                            "type": "object",
                            "properties": {
                              "type": {
                                "type": "string",
                                "description": "Jenis barcode (misalnya `PDF417`, `QR_CODE`, `UNKNOWN`)."
                              },
                              "position": {
                                "type": "object",
                                "nullable": true,
                                "additionalProperties": true,
                                "description": "Lokasi barcode dalam gambar, jika tersedia."
                              },
                              "data": {
                                "type": "string",
                                "description": "Payload yang didekodekan."
                              },
                              "data_raw": {
                                "type": "string",
                                "description": "Payload mentah (belum didekode), jika berbeda."
                              },
                              "side": {
                                "type": "string",
                                "nullable": true,
                                "description": "`front` atau `back`."
                              }
                            }
                          }
                        }
                      }
                    },
                    "vendor_data": {
                      "type": "string",
                      "nullable": true,
                      "description": "Salinan `vendor_data` yang Anda kirimkan, atau `null`."
                    },
                    "metadata": {
                      "type": "object",
                      "nullable": true,
                      "additionalProperties": true,
                      "description": "Salinan objek `metadata` yang Anda kirimkan, atau `null`."
                    },
                    "created_at": {
                      "type": "string",
                      "format": "date-time",
                      "description": "Stempel waktu ISO 8601 (UTC) saat respons dibuat."
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Kesalahan validasi atau pemrosesan. Masalah tingkat kolom mengembalikan envelope standar DRF (satu array pesan per kolom yang bermasalah). Masalah PDF terenkripsi mengembalikan `{\"detail\": ...}`. Gambar dokumen yang dokumennya sama sekali tidak dapat dikenali mengembalikan `{\"error\": \"COULD_NOT_RECOGNIZE_DOCUMENT\"}`. Unggahan PDF juga dapat gagal dengan \"The submitted PDF file is corrupted or invalid.\" atau kesalahan karena tidak ada halaman.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing front image": {
                    "summary": "`front_image` tidak disertakan dalam data formulir",
                    "value": {
                      "front_image": [
                        "No file was submitted."
                      ]
                    }
                  },
                  "Unsupported file extension": {
                    "summary": "Ekstensi file di luar tiff/jpg/jpeg/png/webp/pdf",
                    "value": {
                      "front_image": [
                        "File extension “txt” is not allowed. Allowed extensions are: tiff, jpg, jpeg, png, webp, pdf."
                      ]
                    }
                  },
                  "File too large": {
                    "summary": "Unggahan melebihi batas 10 MB",
                    "value": {
                      "front_image": [
                        "File size should not exceed 10 MB"
                      ]
                    }
                  },
                  "Invalid option value": {
                    "summary": "Opsi hanya menerima DECLINE atau NO_ACTION",
                    "value": {
                      "invalid_mrz_action": [
                        "\"REVIEW\" is not a valid choice."
                      ]
                    }
                  },
                  "Encrypted PDF": {
                    "summary": "PDF diunggah tanpa kata sandi yang diperlukan",
                    "value": {
                      "detail": "The PDF is encrypted. Please upload a decrypted PDF or a photo instead."
                    }
                  },
                  "Wrong PDF password": {
                    "summary": "`front_image_password` / `back_image_password` tidak dapat mendekripsi PDF",
                    "value": {
                      "detail": "The PDF password is incorrect. Please provide the correct password."
                    }
                  },
                  "Document not recognized": {
                    "summary": "Tidak ada dokumen identitas yang terdeteksi di dalam gambar",
                    "value": {
                      "error": "COULD_NOT_RECOGNIZE_DOCUMENT"
                    }
                  },
                  "PDF conversion failure": {
                    "summary": "PDF yang diunggah tidak dapat dikonversi menjadi gambar",
                    "value": {
                      "error": "Failed to convert front image PDF."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Izin ditolak. Dikembalikan ketika header `x-api-key` tidak ada, dan juga ketika saldo organisasi pemanggil tidak dapat mencukupi biaya panggilan tersebut; kunci yang salah, dicabut, atau kedaluwarsa mengembalikan `401`. Kunci yang tidak ada mengembalikan `403` dengan `{\"detail\": ...}`; kunci yang salah, dicabut, atau kedaluwarsa mengembalikan `401`. Kekurangan kredit mengembalikan `403` dengan `{\"error\": ...}` sebelum pemrosesan gambar apa pun terjadi.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing or invalid API key": {
                    "summary": "Tidak ada header `x-api-key`, atau kuncinya tidak valid/dicabut",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Not enough credits": {
                    "summary": "Saldo organisasi tidak mencukupi untuk panggilan ini",
                    "value": {
                      "error": "You don't have enough credits to perform this request. Please top up at https://business.didit.me"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Batas laju terlampaui. Endpoint POST/PATCH/DELETE berbagi anggaran 300 permintaan penulisan per menit per kunci API (pembuatan transaksi dan ingesti event memiliki anggaran terpisah sebesar 600). Respons menyertakan header `X-RateLimit-Limit`, `X-RateLimit-Remaining`, `X-RateLimit-Reset`, dan `Retry-After`.",
            "content": {
              "application/json": {
                "examples": {
                  "Write rate limit exceeded": {
                    "summary": "Lebih dari 300 permintaan tulis pada menit ini",
                    "value": {
                      "detail": "Write request rate limit exceeded. You can make up to 300 requests per minute."
                    }
                  }
                },
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "503": {
            "$ref": "#/components/responses/DocumentProcessingBusy"
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL",
            "source": "curl -X POST 'https://verification.didit.me/v3/id-verification/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -F 'front_image=@./id_front.jpg' \\\n  -F 'back_image=@./id_back.jpg' \\\n  -F 'perform_document_liveness=true' \\\n  -F 'save_api_request=true' \\\n  -F 'vendor_data=user-123'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.id_verification.verify(\n    front_image=open(\"front_image.jpg\", \"rb\"),\n    back_image=open(\"back_image.jpg\", \"rb\"),\n    perform_document_liveness=True,\n    save_api_request=True,\n    vendor_data=\"user-123\",\n    metadata={\"flow\": \"onboarding\"},\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit, { fileFromPath } from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.idVerification.verify({\n  front_image: await fileFromPath(\"front_image.jpg\"),\n  back_image: await fileFromPath(\"back_image.jpg\"),\n  perform_document_liveness: true,\n  save_api_request: true,\n  vendor_data: \"user-123\",\n  metadata: { flow: \"onboarding\" },\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.IDVerification.Verify(ctx, didit.IDVerificationVerifyParams{\n\tFrontImage:              didit.FileFromPath(\"front_image.jpg\"),\n\tBackImage:               didit.Some(didit.FileFromPath(\"back_image.jpg\")),\n\tPerformDocumentLiveness: didit.Bool(true),\n\tSaveAPIRequest:          didit.Bool(true),\n\tVendorData:              didit.String(\"user-123\"),\n\tMetadata:                didit.Some(map[string]any{\"flow\": \"onboarding\"}),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.nio.file.Path;\nimport java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.IdVerificationVerifyParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.idVerification().verify(IdVerificationVerifyParams.builder()\n        .frontImage(Path.of(\"front_image.jpg\"))\n        .backImage(Path.of(\"back_image.jpg\"))\n        .performDocumentLiveness(true)\n        .saveApiRequest(true)\n        .vendorData(\"user-123\")\n        .metadata(Map.of(\"flow\", \"onboarding\"))\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\nuse Didit\\File;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->idVerification->verify([\n    'front_image' => File::fromPath('front_image.jpg'),\n    'back_image' => File::fromPath('back_image.jpg'),\n    'perform_document_liveness' => true,\n    'save_api_request' => true,\n    'vendor_data' => 'user-123',\n    'metadata' => ['flow' => 'onboarding'],\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.id_verification.verify(\n  front_image: Pathname(\"front_image.jpg\"),\n  back_image: Pathname(\"back_image.jpg\"),\n  perform_document_liveness: true,\n  save_api_request: true,\n  vendor_data: \"user-123\",\n  metadata: { flow: \"onboarding\" }\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.IdVerification.VerifyAsync(new IdVerificationVerifyParams\n{\n    FrontImage = FileUpload.FromPath(\"front_image.jpg\"),\n    BackImage = FileUpload.FromPath(\"back_image.jpg\"),\n    PerformDocumentLiveness = true,\n    SaveApiRequest = true,\n    VendorData = \"user-123\",\n    Metadata = new Dictionary<string, object> { [\"flow\"] = \"onboarding\" },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/face-match/": {
      "post": {
        "summary": "Pencocokan Wajah",
        "description": "Bandingkan dua gambar wajah (1:1) dan dapatkan `score` kemiripan (0–100) serta `status` `Approved`/`Declined`.\n\n**Cara kerjanya.** Kedua gambar didekodekan dan dianalisis oleh model biometrik (atur `rotate_image=true` jika pengambilan gambar mungkin miring atau terbalik), lalu skor kemiripan antara kedua wajah dihitung. Skor yang **benar-benar di atas** `face_match_score_decline_threshold` (default `30`) mengembalikan `status: \"Approved\"`; skor yang sama dengan atau di bawahnya mengembalikan `Declined` dengan peringatan `LOW_FACE_MATCH_SIMILARITY`. Jika tidak ada pasangan wajah yang dapat dinilai sama sekali, panggilan tetap mengembalikan `200` dengan `status: \"Declined\"` dan peringatan `NO_REFERENCE_IMAGE` — `score` bernilai `null` pada jalur penyimpanan default, atau `0` dengan `save_api_request=false`. Kirimkan satu wajah yang jelas dan menghadap ke depan per gambar untuk hasil terbaik.\n\n**Penagihan.** Setiap respons `200` menggunakan satu kredit API Pencocokan Wajah (dibayar dari kredit paket atau saldo isi ulang Anda). Jika saldo organisasi tidak dapat mencukupi panggilan, endpoint mengembalikan `403` dengan kesalahan \"kredit tidak mencukupi\" sebelum pemrosesan gambar apa pun.\n\n**Persistensi sesi (`save_api_request`, default `true`).** Jika `true`, panggilan disimpan secara persisten sebagai sesi bertipe API: sesi ini muncul di Business Console, `request_id` yang dikembalikan adalah id sesi sebenarnya yang dapat Anda teruskan ke `GET /v3/session/{sessionId}/decision/`, kedua gambar disimpan sebagai gambar sumber/target pencocokan wajah sesi tersebut, dan webhook `status.updated` dipancarkan ke endpoint webhook yang Anda konfigurasi. Jika `false`, tidak ada yang disimpan dan `request_id` adalah UUID korelasi satu kali yang tidak dapat dicari kemudian.\n\n**Indeks pencarian wajah.** Endpoint ini tidak pernah mendaftarkan wajah ke dalam indeks pencarian wajah Anda dan tidak pernah menjalankan skrining daftar blokir atau duplikat — gunakan `POST /v3/passive-liveness/` atau `POST /v3/face-search/` untuk keperluan tersebut.\n\n**Sandbox.** Kunci API sandbox melewati semua pemrosesan dan penagihan: setelah validasi permintaan (input yang salah format tetap mengembalikan `400`), endpoint mengembalikan payload tiruan statis `Approved`, tidak ada sesi yang disimpan, dan tidak ada kredit yang digunakan.\n\n**Autentikasi.** Kirim kunci API aplikasi Anda di header `x-api-key`. Kredensial yang hilang atau tidak valid mengembalikan `403` (`{\"detail\": \"You do not have permission to perform this action.\"}`) — API ini tidak pernah mengembalikan `401`.\n\n**Batas laju.** Batas bersama untuk 300 permintaan tulis per menit per kunci API di seluruh endpoint POST/PATCH/DELETE; melebihi batas ini mengembalikan `429`.",
        "operationId": "post_v3face-match",
        "x-didit-sdk": {
          "resource": "face_match",
          "method": "compare",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Standalone APIs"
        ],
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "required": [
                  "user_image",
                  "ref_image"
                ],
                "properties": {
                  "user_image": {
                    "type": "string",
                    "format": "binary",
                    "description": "Gambar wajah nyata atau kandidat yang akan diverifikasi (misalnya swafoto). Kirim satu foto menghadap ke depan dengan wajah subjek terlihat jelas dan pencahayaan baik. Ekstensi yang diizinkan: `tiff`, `jpg`, `jpeg`, `png`, `webp`. Ukuran unggahan maksimum: **5 MB** (file yang lebih besar ditolak dengan `400`). Gambar secara otomatis dikompresi menjadi ~0.5 MB sebelum diproses, sehingga resolusi yang sangat tinggi tidak meningkatkan akurasi."
                  },
                  "ref_image": {
                    "type": "string",
                    "format": "binary",
                    "description": "Gambar wajah referensi untuk dibandingkan (misalnya foto dokumen identitas atau foto yang didaftarkan sebelumnya). Format dan batas ukuran sama seperti `user_image`."
                  },
                  "face_match_score_decline_threshold": {
                    "type": "number",
                    "format": "float",
                    "default": 30,
                    "minimum": 0,
                    "maximum": 100,
                    "description": "Ambang batas kemiripan (0–100) yang menentukan respons `status`. Skor terhitung **pada atau di bawah** nilai ini akan menetapkan `status` menjadi `Declined` dan menambahkan peringatan `LOW_FACE_MATCH_SIMILARITY`; skor yang secara ketat berada di atasnya mengembalikan `Approved`. Nilai default `30` bersifat permisif — naikkan nilainya (misalnya `50`–`60`) untuk verifikasi yang lebih ketat. Nilai di luar 0–100 mengembalikan `400`.",
                    "example": 50
                  },
                  "rotate_image": {
                    "type": "boolean",
                    "default": false,
                    "description": "Jika `true`, layanan mencoba gambar-gambar input dalam kelipatan 90 derajat (0, 90, 180, 270) dan menggunakan orientasi yang menghasilkan deteksi wajah terbaik — berguna untuk pengambilan gambar seluler dengan orientasi EXIF yang hilang. Menambah latensi, jadi aktifkan hanya jika Anda tidak dapat menjamin gambar dalam posisi tegak.",
                    "example": false
                  },
                  "save_api_request": {
                    "type": "boolean",
                    "default": true,
                    "description": "Jika `true` (default), menyimpan panggilan sebagai sesi tipe API — terlihat di Business Console, dapat diambil melalui `GET /v3/session/{sessionId}/decision/` menggunakan `request_id` yang dikembalikan, dan diumumkan melalui webhook `status.updated`. Jika `false`, tidak ada yang disimpan dan `request_id` adalah UUID sementara hanya untuk korelasi respons.",
                    "example": true
                  },
                  "vendor_data": {
                    "type": "string",
                    "description": "String buram opsional (ID pengguna internal, email, UUID Anda…) yang disimpan pada sesi yang dipertahankan dan dikembalikan dalam respons. Gunakan untuk mengorelasikan panggilan API dengan catatan Anda sendiri dan memfilter sesi nantinya.",
                    "example": "user-123"
                  },
                  "metadata": {
                    "type": "object",
                    "additionalProperties": true,
                    "description": "Objek JSON opsional yang disimpan bersama sesi (saat `save_api_request=true`) dan dikembalikan dalam respons. Dalam permintaan multipart, kirimkan sebagai kolom string yang dikodekan dalam JSON (misalnya `metadata={\"flow\":\"login\"}`) — kolom ini akan diuraikan menjadi sebuah objek.",
                    "example": {
                      "flow": "login",
                      "device_id": "abc123"
                    }
                  }
                }
              },
              "example": {
                "user_image": "(binary JPEG/PNG of the live selfie)",
                "ref_image": "(binary JPEG/PNG of the reference photo)",
                "face_match_score_decline_threshold": 50,
                "rotate_image": false,
                "save_api_request": true,
                "vendor_data": "user-123",
                "metadata": {
                  "flow": "login"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Pencocokan wajah telah dihitung. `face_match.score` adalah float 0–100 (dua desimal); `status` adalah `Approved` ketika skor secara ketat di atas `face_match_score_decline_threshold`, jika tidak `Declined` dengan peringatan penjelas. Pasangan dengan kemiripan rendah atau tidak dapat dinilai tetap mengembalikan `200` — periksa `face_match.status` dan `face_match.warnings`, bukan hanya kode HTTP. Ketika `save_api_request=true`, `request_id` adalah id sesi yang disimpan.",
            "content": {
              "application/json": {
                "examples": {
                  "Approved": {
                    "summary": "Orang yang sama — skor di atas ambang batas",
                    "value": {
                      "request_id": "f9f5a777-8002-44c6-baaf-128bcfd6e226",
                      "face_match": {
                        "status": "Approved",
                        "score": 99.41,
                        "user_image": {
                          "entities": [
                            {
                              "bbox": [
                                661,
                                728,
                                1688,
                                2188
                              ],
                              "confidence": 0.732973,
                              "age": 26.91,
                              "gender": "male",
                              "race": null
                            }
                          ],
                          "best_angle": 0
                        },
                        "ref_image": {
                          "entities": [
                            {
                              "bbox": [
                                653,
                                745,
                                1691,
                                2185
                              ],
                              "confidence": 0.722082,
                              "age": 27.0,
                              "gender": "male",
                              "race": null
                            }
                          ],
                          "best_angle": 0
                        },
                        "warnings": []
                      },
                      "vendor_data": "user-123",
                      "metadata": {
                        "flow": "login"
                      },
                      "created_at": "2026-06-12T01:04:42.763237+00:00"
                    }
                  },
                  "Declined - low similarity": {
                    "summary": "Skor pada atau di bawah ambang batas penolakan",
                    "value": {
                      "request_id": "7cdda24e-311a-46d3-a3bb-e5d9b564ce73",
                      "face_match": {
                        "status": "Declined",
                        "score": 24.87,
                        "user_image": {
                          "entities": [
                            {
                              "bbox": [
                                661,
                                728,
                                1688,
                                2188
                              ],
                              "confidence": 0.732973,
                              "age": 26.91,
                              "gender": "male",
                              "race": null
                            }
                          ],
                          "best_angle": 0
                        },
                        "ref_image": {
                          "entities": [
                            {
                              "bbox": [
                                156,
                                234,
                                679,
                                898
                              ],
                              "confidence": 0.717775,
                              "age": 41.2,
                              "gender": "male",
                              "race": null
                            }
                          ],
                          "best_angle": 0
                        },
                        "warnings": [
                          {
                            "risk": "LOW_FACE_MATCH_SIMILARITY",
                            "feature": "FACEMATCH",
                            "additional_data": null,
                            "log_type": "error",
                            "short_description": "Low face match similarity",
                            "long_description": "The facial features of the provided image don't closely match the reference image, suggesting a potential identity mismatch."
                          }
                        ]
                      },
                      "vendor_data": "user-123",
                      "metadata": null,
                      "created_at": "2026-06-12T01:08:19.859116+00:00"
                    }
                  }
                },
                "schema": {
                  "type": "object",
                  "properties": {
                    "request_id": {
                      "type": "string",
                      "format": "uuid",
                      "description": "ID sesi yang disimpan saat `save_api_request=true` (dapat digunakan dengan `GET /v3/session/{sessionId}/decision/`); jika tidak, berupa UUID korelasi sementara."
                    },
                    "face_match": {
                      "type": "object",
                      "properties": {
                        "status": {
                          "type": "string",
                          "enum": [
                            "Approved",
                            "Declined"
                          ],
                          "description": "`Approved` ketika skor kemiripan secara ketat berada di atas `face_match_score_decline_threshold` dan skor dapat dihitung; `Declined` jika tidak (peringatan menjelaskan alasannya)."
                        },
                        "score": {
                          "type": "number",
                          "format": "float",
                          "nullable": true,
                          "minimum": 0,
                          "maximum": 100,
                          "description": "Skor kemiripan dari 0 hingga 100 — tingkat keyakinan model bahwa kedua gambar menggambarkan orang yang sama. Dibulatkan menjadi dua desimal hanya saat `save_api_request` bernilai true; dengan `save_api_request=false`, nilai float mentah dikembalikan. `null` jika tidak ada pasangan wajah yang dapat dinilai (dengan default `save_api_request=true`); dengan `save_api_request=false`, kondisi yang sama dapat muncul sebagai `score: 0`. Bagaimanapun, peringatan `NO_REFERENCE_IMAGE` akan muncul dan `status` bernilai `Declined`.",
                          "example": 99.41
                        },
                        "user_image": {
                          "type": "object",
                          "description": "Hasil deteksi wajah untuk gambar yang dianalisis.",
                          "properties": {
                            "entities": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "bbox": {
                                    "type": "array",
                                    "items": {
                                      "type": "integer"
                                    },
                                    "minItems": 4,
                                    "maxItems": 4,
                                    "description": "Bounding box wajah yang terdeteksi sebagai koordinat piksel `[x_min, y_min, x_max, y_max]` pada gambar yang diproses.",
                                    "example": [
                                      661,
                                      728,
                                      1688,
                                      2188
                                    ]
                                  },
                                  "confidence": {
                                    "type": "number",
                                    "format": "float",
                                    "minimum": 0,
                                    "maximum": 1,
                                    "description": "Skor keyakinan deteksi wajah (0–1).",
                                    "example": 0.732973
                                  },
                                  "age": {
                                    "type": "number",
                                    "format": "float",
                                    "description": "Usia yang diestimasi oleh model dari wajah yang terdeteksi, dalam tahun. Hanya bersifat informasi — ini tidak memengaruhi keputusan Pencocokan Wajah.",
                                    "example": 26.91
                                  },
                                  "gender": {
                                    "type": "string",
                                    "description": "Jenis kelamin yang diprediksi oleh model dari wajah yang terdeteksi (`male` atau `female`). Hanya bersifat informasi.",
                                    "example": "male"
                                  },
                                  "race": {
                                    "type": "string",
                                    "nullable": true,
                                    "description": "Kolom yang dicadangkan — selalu bernilai `null` dalam respons dari endpoint ini.",
                                    "example": null
                                  }
                                }
                              },
                              "description": "Satu entri per wajah yang terdeteksi."
                            },
                            "best_angle": {
                              "type": "integer",
                              "description": "Rotasi (derajat: 0, 90, 180, atau 270) yang menghasilkan deteksi wajah terbaik. Hanya bernilai bukan nol jika `rotate_image=true` mengoreksi orientasi.",
                              "example": 0
                            }
                          }
                        },
                        "ref_image": {
                          "type": "object",
                          "description": "Hasil deteksi wajah untuk gambar referensi, bentuk yang sama seperti `user_image`.",
                          "properties": {
                            "entities": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "bbox": {
                                    "type": "array",
                                    "items": {
                                      "type": "integer"
                                    },
                                    "minItems": 4,
                                    "maxItems": 4,
                                    "description": "Bounding box wajah yang terdeteksi sebagai koordinat piksel `[x_min, y_min, x_max, y_max]` pada gambar yang diproses.",
                                    "example": [
                                      661,
                                      728,
                                      1688,
                                      2188
                                    ]
                                  },
                                  "confidence": {
                                    "type": "number",
                                    "format": "float",
                                    "minimum": 0,
                                    "maximum": 1,
                                    "description": "Skor keyakinan deteksi wajah (0–1).",
                                    "example": 0.732973
                                  },
                                  "age": {
                                    "type": "number",
                                    "format": "float",
                                    "description": "Usia yang diestimasi oleh model dari wajah yang terdeteksi, dalam tahun. Hanya bersifat informasi — ini tidak memengaruhi keputusan Pencocokan Wajah.",
                                    "example": 26.91
                                  },
                                  "gender": {
                                    "type": "string",
                                    "description": "Jenis kelamin yang diprediksi oleh model dari wajah yang terdeteksi (`male` atau `female`). Hanya bersifat informasi.",
                                    "example": "male"
                                  },
                                  "race": {
                                    "type": "string",
                                    "nullable": true,
                                    "description": "Kolom yang dicadangkan — selalu bernilai `null` dalam respons dari endpoint ini.",
                                    "example": null
                                  }
                                }
                              },
                              "description": "Satu entri per wajah yang terdeteksi."
                            },
                            "best_angle": {
                              "type": "integer",
                              "example": 0
                            }
                          }
                        },
                        "warnings": {
                          "type": "array",
                          "description": "Kosong jika persetujuan bersih. `NO_REFERENCE_IMAGE` (`error`) — pasangan wajah tidak dapat dinilai; `LOW_FACE_MATCH_SIMILARITY` (`error`) — skor berada pada atau di bawah ambang batas penolakan. Salah satu dari kondisi ini akan menetapkan `status` ke `Declined`.",
                          "items": {
                            "type": "object",
                            "properties": {
                              "risk": {
                                "type": "string",
                                "enum": [
                                  "NO_REFERENCE_IMAGE",
                                  "LOW_FACE_MATCH_SIMILARITY"
                                ],
                                "description": "Kode risiko yang dapat dibaca mesin."
                              },
                              "feature": {
                                "type": "string",
                                "enum": [
                                  "FACEMATCH"
                                ],
                                "description": "Fitur yang memunculkan peringatan. Selalu `FACEMATCH` pada endpoint ini."
                              },
                              "additional_data": {
                                "type": "object",
                                "nullable": true,
                                "additionalProperties": true,
                                "description": "Selalu `null` untuk peringatan pencocokan wajah."
                              },
                              "log_type": {
                                "type": "string",
                                "enum": [
                                  "error",
                                  "warning",
                                  "information"
                                ],
                                "description": "Tingkat keparahan. Peringatan `error` mendorong `status` menjadi `Declined`; entri `warning` dan `information` bersifat anjuran dan tidak pernah menolak dengan sendirinya."
                              },
                              "short_description": {
                                "type": "string",
                                "description": "Ringkasan satu baris yang dapat dibaca manusia tentang risiko."
                              },
                              "long_description": {
                                "type": "string",
                                "description": "Penjelasan risiko yang mudah dibaca manusia."
                              }
                            }
                          }
                        }
                      }
                    },
                    "vendor_data": {
                      "type": "string",
                      "nullable": true,
                      "description": "Salinan `vendor_data` yang Anda kirimkan, atau `null`."
                    },
                    "metadata": {
                      "type": "object",
                      "nullable": true,
                      "additionalProperties": true,
                      "description": "Salinan objek `metadata` yang Anda kirimkan, atau `null`."
                    },
                    "created_at": {
                      "type": "string",
                      "format": "date-time",
                      "description": "Stempel waktu ISO 8601 (UTC) saat respons dibuat, misalnya `2026-06-12T01:04:42.763237+00:00`."
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Kesalahan validasi. Dikembalikan ketika gambar yang diperlukan tidak ada, melebihi 5 MB, memiliki ekstensi yang tidak didukung, atau ketika sebuah opsi berada di luar rentang. Isi respons adalah envelope kesalahan kolom standar DRF: satu array pesan per kolom yang bermasalah.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing required image": {
                    "summary": "`ref_image` (atau `user_image`) tidak disertakan di dalam data formulir",
                    "value": {
                      "ref_image": [
                        "No file was submitted."
                      ]
                    }
                  },
                  "Unsupported file extension": {
                    "summary": "Ekstensi file di luar 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": "Unggahan melebihi batas 5 MB",
                    "value": {
                      "user_image": [
                        "File size should not exceed 5 MB"
                      ]
                    }
                  },
                  "Threshold out of range": {
                    "summary": "`face_match_score_decline_threshold` di luar rentang 0–100",
                    "value": {
                      "face_match_score_decline_threshold": [
                        "Ensure this value is less than or equal to 100."
                      ]
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Izin ditolak. Dikembalikan ketika header `x-api-key` tidak ada, dan juga ketika saldo organisasi pemanggil tidak dapat mencukupi biaya panggilan tersebut; kunci yang salah, dicabut, atau kedaluwarsa mengembalikan `401`. Kunci yang tidak ada mengembalikan `403` dengan `{\"detail\": ...}`; kunci yang salah, dicabut, atau kedaluwarsa mengembalikan `401`. Kekurangan kredit mengembalikan `403` dengan `{\"error\": ...}` sebelum pemrosesan gambar apa pun terjadi.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing or invalid API key": {
                    "summary": "Tidak ada header `x-api-key`, atau kuncinya tidak valid/dicabut",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Not enough credits": {
                    "summary": "Saldo organisasi tidak mencukupi untuk panggilan ini",
                    "value": {
                      "error": "You don't have enough credits to perform this request. Please top up at https://business.didit.me"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Batas laju terlampaui. Endpoint POST/PATCH/DELETE berbagi anggaran 300 permintaan penulisan per menit per kunci API (pembuatan transaksi dan ingesti event memiliki anggaran terpisah sebesar 600). Respons menyertakan header `X-RateLimit-Limit`, `X-RateLimit-Remaining`, `X-RateLimit-Reset`, dan `Retry-After`.",
            "content": {
              "application/json": {
                "examples": {
                  "Write rate limit exceeded": {
                    "summary": "Lebih dari 300 permintaan tulis pada menit ini",
                    "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-match/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -F 'user_image=@./selfie.jpg' \\\n  -F 'ref_image=@./id_portrait.jpg' \\\n  -F 'face_match_score_decline_threshold=50' \\\n  -F 'save_api_request=true' \\\n  -F 'vendor_data=user-123'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.face_match.compare(\n    user_image=open(\"user_image.jpg\", \"rb\"),\n    ref_image=open(\"ref_image.jpg\", \"rb\"),\n    face_match_score_decline_threshold=50.0,\n    rotate_image=False,\n    save_api_request=True,\n    vendor_data=\"user-123\",\n    metadata={\"flow\": \"login\"},\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit, { fileFromPath } from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.faceMatch.compare({\n  user_image: await fileFromPath(\"user_image.jpg\"),\n  ref_image: await fileFromPath(\"ref_image.jpg\"),\n  face_match_score_decline_threshold: 50.0,\n  rotate_image: false,\n  save_api_request: true,\n  vendor_data: \"user-123\",\n  metadata: { flow: \"login\" },\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.FaceMatch.Compare(ctx, didit.FaceMatchCompareParams{\n\tUserImage:                      didit.FileFromPath(\"user_image.jpg\"),\n\tRefImage:                       didit.FileFromPath(\"ref_image.jpg\"),\n\tFaceMatchScoreDeclineThreshold: didit.Float(50.0),\n\tRotateImage:                    didit.Bool(false),\n\tSaveAPIRequest:                 didit.Bool(true),\n\tVendorData:                     didit.String(\"user-123\"),\n\tMetadata:                       didit.Some(map[string]any{\"flow\": \"login\"}),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.nio.file.Path;\nimport java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.FaceMatchCompareParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.faceMatch().compare(FaceMatchCompareParams.builder()\n        .userImage(Path.of(\"user_image.jpg\"))\n        .refImage(Path.of(\"ref_image.jpg\"))\n        .faceMatchScoreDeclineThreshold(50.0)\n        .rotateImage(false)\n        .saveApiRequest(true)\n        .vendorData(\"user-123\")\n        .metadata(Map.of(\"flow\", \"login\"))\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\nuse Didit\\File;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->faceMatch->compare([\n    'user_image' => File::fromPath('user_image.jpg'),\n    'ref_image' => File::fromPath('ref_image.jpg'),\n    'face_match_score_decline_threshold' => 50.0,\n    'rotate_image' => false,\n    'save_api_request' => true,\n    'vendor_data' => 'user-123',\n    'metadata' => ['flow' => 'login'],\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.face_match.compare(\n  user_image: Pathname(\"user_image.jpg\"),\n  ref_image: Pathname(\"ref_image.jpg\"),\n  face_match_score_decline_threshold: 50.0,\n  rotate_image: false,\n  save_api_request: true,\n  vendor_data: \"user-123\",\n  metadata: { flow: \"login\" }\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.FaceMatch.CompareAsync(new FaceMatchCompareParams\n{\n    UserImage = FileUpload.FromPath(\"user_image.jpg\"),\n    RefImage = FileUpload.FromPath(\"ref_image.jpg\"),\n    FaceMatchScoreDeclineThreshold = 50.0,\n    RotateImage = false,\n    SaveApiRequest = true,\n    VendorData = \"user-123\",\n    Metadata = new Dictionary<string, object> { [\"flow\"] = \"login\" },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/age-estimation/": {
      "post": {
        "summary": "Estimasi Usia (usia wajah + deteksi liveness pasif)",
        "description": "Estimasi usia seseorang dari satu foto wajah dan jalankan pemeriksaan liveness pasif dalam panggilan yang sama — mengembalikan `age_estimation` yang diprediksi model (dalam tahun), `score` liveness (0–100), dan `status` `Approved`/`Declined`. Usia ini **diprediksi model dari wajah, bukan diverifikasi terhadap dokumen** — gunakan untuk pembatasan usia dan pemeriksaan tanpa hambatan, bukan sebagai bukti usia yang sah.\n\n**Cara kerjanya.** Gambar dianalisis untuk mendeteksi wajah (atur `rotate_image=true` jika hasil pengambilan gambar miring atau terbalik); setiap wajah yang terdeteksi mendapatkan estimasi usia, dan wajah terbesar di dalam bingkai menentukan `age_estimation`. Secara paralel, model liveness pasif menilai apakah foto menampilkan orang sungguhan (tidak memerlukan tantangan pengguna) dan mendeteksi serangan presentasi (foto dari foto, layar, topeng). Kirim satu wajah yang jelas, menghadap ke depan, dan berpenerangan baik per gambar untuk hasil terbaik.\n\n**Logika keputusan.** Setiap peringatan menghasilkan penolakan: `status` menjadi `Approved` hanya jika larik `warnings` kosong. `score` liveness pada atau di bawah `face_liveness_score_decline_threshold` (default `30`) menambahkan `LOW_LIVENESS_SCORE`; serangan yang terdeteksi menambahkan `LIVENESS_FACE_ATTACK`; tidak ada wajah yang ditemukan oleh model liveness menambahkan `NO_FACE_DETECTED`; tidak ada usia wajah yang dapat diestimasi menambahkan `AGE_NOT_DETECTED` (`age_estimation` bernilai `null`); estimasi usia di bawah `age_estimation_decline_threshold` (default `18`) menambahkan `AGE_BELOW_MINIMUM`. Usia yang mendekati ambang batas Anda sebaiknya dialihkan ke verifikasi berbasis dokumen — tingkat kesalahan model meningkat untuk wajah yang mendekati batas tersebut.\n\n**Penagihan.** Setiap respons `200` menggunakan satu kredit API Estimasi Usia (dibayar dari kredit paket atau saldo isi ulang Anda). Ketika saldo organisasi tidak mencukupi untuk panggilan tersebut, endpoint mengembalikan `403` dengan kesalahan kredit tidak mencukupi sebelum pemrosesan gambar apa pun.\n\n**Persistensi sesi (`save_api_request`, default `true`).** Jika bernilai `true`, panggilan disimpan sebagai sesi tipe API: sesi tersebut muncul di Business Console, `request_id` yang dikembalikan adalah id sesi sebenarnya yang dapat Anda teruskan ke `GET /v3/session/{sessionId}/decision/` (hasilnya ditampilkan di sana dalam `liveness_checks[]`, dengan `features: [\"AGE_ESTIMATION\"]`), potongan wajah dan gambar referensi disimpan, embedding wajah ditambahkan ke indeks wajah aplikasi Anda (digunakan oleh pencarian wajah dan deteksi duplikat), dan webhook `status.updated` dikirimkan. Jika bernilai `false`, tidak ada yang disimpan dan `request_id` merupakan UUID korelasi sekali pakai yang tidak dapat dicari kemudian.\n\n**Sandbox.** Kunci API sandbox melewati semua pemrosesan dan penagihan: setelah validasi permintaan (input yang salah format tetap mengembalikan `400`), endpoint mengembalikan payload tiruan `Approved` statis (`age_estimation: 30`, tanpa peringatan), tidak ada sesi yang disimpan, dan tidak ada kredit yang digunakan.\n\n**Autentikasi.** Kirim kunci API aplikasi Anda di header `x-api-key`. Kredensial yang hilang atau tidak valid mengembalikan `403` (`{\"detail\": \"You do not have permission to perform this action.\"}`) — API ini tidak pernah mengembalikan `401`.\n\n**Batas laju.** Anggaran tulis bersama sebesar 300 permintaan/menit per kunci API di semua endpoint POST/PATCH/DELETE; melampauinya akan mengembalikan `429`.",
        "operationId": "post_v3age-estimation",
        "x-didit-sdk": {
          "resource": "age_estimation",
          "method": "estimate",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Standalone APIs"
        ],
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "required": [
                  "user_image"
                ],
                "properties": {
                  "user_image": {
                    "type": "string",
                    "format": "binary",
                    "description": "Foto wajah yang akan dianalisis (misalnya swafoto). Kirimkan satu foto menghadap ke depan dengan wajah subjek terlihat jelas dan dengan pencahayaan yang baik. Ekstensi yang diizinkan: `tiff`, `jpg`, `jpeg`, `png`, `webp` (tanpa PDF). Ukuran unggahan maksimum: **5 MB** (file yang lebih besar ditolak dengan `400`). Gambar secara otomatis dikompresi menjadi ~0.3 MB sebelum diproses, sehingga resolusi yang sangat tinggi tidak meningkatkan akurasi."
                  },
                  "face_liveness_score_decline_threshold": {
                    "type": "number",
                    "format": "float",
                    "default": 30,
                    "minimum": 0,
                    "maximum": 100,
                    "description": "Ambang batas liveness (0–100). `score` liveness **pada atau di bawah** nilai ini menambahkan peringatan `LOW_LIVENESS_SCORE` dan menolak. Naikkan untuk anti-spoofing yang lebih ketat; nilai di luar 0–100 mengembalikan `400`.",
                    "example": 30
                  },
                  "age_estimation_decline_threshold": {
                    "type": "integer",
                    "default": 18,
                    "minimum": 0,
                    "maximum": 100,
                    "description": "Estimasi usia minimum yang dapat diterima dalam tahun. Estimasi usia **di bawah** nilai ini akan menambahkan peringatan `AGE_BELOW_MINIMUM` dan ditolak. Atur `0` untuk menonaktifkan pemeriksaan usia (panggilan kemudian hanya menjalankan liveness + estimasi usia tanpa keputusan berbasis usia).",
                    "example": 18
                  },
                  "rotate_image": {
                    "type": "boolean",
                    "default": false,
                    "description": "Jika `true`, layanan mencoba gambar input dalam kelipatan 90 derajat (0, 90, 180, 270) dan menggunakan orientasi yang menghasilkan deteksi wajah terbaik — berguna untuk pengambilan gambar seluler dengan orientasi EXIF yang hilang. Menambah latensi, jadi aktifkan hanya jika Anda tidak dapat menjamin gambar dalam posisi tegak.",
                    "example": false
                  },
                  "save_api_request": {
                    "type": "boolean",
                    "default": true,
                    "description": "Jika `true` (default), menyimpan panggilan sebagai sesi tipe API — terlihat di Business Console, dapat diambil melalui `GET /v3/session/{sessionId}/decision/` menggunakan `request_id` yang dikembalikan, diumumkan melalui webhook `status.updated`, dan dengan wajah yang terdeteksi ditambahkan ke indeks wajah aplikasi Anda. Jika `false`, tidak ada yang disimpan dan `request_id` adalah UUID sementara hanya untuk korelasi respons.",
                    "example": true
                  },
                  "vendor_data": {
                    "type": "string",
                    "description": "String buram opsional (ID pengguna internal, email, UUID Anda…) yang disimpan pada sesi yang dipertahankan dan dikembalikan dalam respons. Gunakan untuk mengorelasikan panggilan API dengan catatan Anda sendiri dan memfilter sesi nantinya.",
                    "example": "user-123"
                  },
                  "metadata": {
                    "type": "object",
                    "additionalProperties": true,
                    "description": "Objek JSON opsional yang disimpan bersama sesi (saat `save_api_request=true`) dan dikembalikan dalam respons. Dalam permintaan multipart, kirimkan sebagai kolom string yang dikodekan dalam JSON (misalnya `metadata={\"flow\":\"age-gate\"}`) — kolom ini akan diuraikan menjadi sebuah objek.",
                    "example": {
                      "flow": "age-gate"
                    }
                  }
                }
              },
              "example": {
                "user_image": "(binary JPEG/PNG of the selfie)",
                "face_liveness_score_decline_threshold": 30,
                "age_estimation_decline_threshold": 18,
                "rotate_image": false,
                "save_api_request": true,
                "vendor_data": "user-123",
                "metadata": {
                  "flow": "age-gate"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Estimasi usia dan deteksi liveness pasif selesai. `age_estimation.age_estimation` adalah usia yang diprediksi model dalam tahun dari wajah terbesar yang terdeteksi (`null` jika tidak ada); `age_estimation.score` adalah skor deteksi liveness pasif (0–100); `status` bernilai `Approved` hanya jika `warnings` kosong. Pengambilan gambar oleh pengguna di bawah umur atau hasil spoofing tetap mengembalikan `200` dengan `status: \"Declined\"` — periksa isi respons, bukan hanya kode HTTP. Jika `save_api_request=true`, `request_id` adalah ID sesi yang tersimpan.",
            "content": {
              "application/json": {
                "examples": {
                  "Approved": {
                    "summary": "Wajah nyata orang dewasa — kedua pemeriksaan lolos",
                    "value": {
                      "request_id": "0c40ba43-64ab-4e2e-b4b8-7d1f12f81bc1",
                      "age_estimation": {
                        "status": "Approved",
                        "method": "PASSIVE",
                        "score": 97.5,
                        "user_image": {
                          "entities": [
                            {
                              "age": 27.33,
                              "bbox": [
                                40,
                                40,
                                100,
                                100
                              ],
                              "confidence": 0.7177750468254089,
                              "gender": "male"
                            }
                          ],
                          "best_angle": 0
                        },
                        "age_estimation": 27.33,
                        "warnings": []
                      },
                      "vendor_data": "user-123",
                      "metadata": {
                        "flow": "age-gate"
                      },
                      "created_at": "2026-06-12T02:24:11.512941+00:00"
                    }
                  },
                  "Declined - age below threshold": {
                    "summary": "Usia hasil estimasi di bawah `age_estimation_decline_threshold`",
                    "value": {
                      "request_id": "9be41a6f-2f4e-4f57-92f4-b3a4f6f0a1c2",
                      "age_estimation": {
                        "status": "Declined",
                        "method": "PASSIVE",
                        "score": 95.0,
                        "user_image": {
                          "entities": [
                            {
                              "age": 16.5,
                              "bbox": [
                                40,
                                40,
                                100,
                                100
                              ],
                              "confidence": 0.7177750468254089,
                              "gender": "female"
                            }
                          ],
                          "best_angle": 0
                        },
                        "age_estimation": 16.5,
                        "warnings": [
                          {
                            "risk": "AGE_BELOW_MINIMUM",
                            "feature": "LIVENESS",
                            "additional_data": null,
                            "log_type": "error",
                            "short_description": "Age below minimum",
                            "long_description": "The age of the face is below the minimum age threshold for the application."
                          }
                        ]
                      },
                      "vendor_data": "user-123",
                      "metadata": null,
                      "created_at": "2026-06-12T02:26:40.118332+00:00"
                    }
                  },
                  "Declined - liveness too low": {
                    "summary": "Skor liveness pada atau di bawah ambang batas penolakan (kemungkinan spoofing)",
                    "value": {
                      "request_id": "5f6f2f1f-7c4f-43b9-8d62-0a8f4c2d9e77",
                      "age_estimation": {
                        "status": "Declined",
                        "method": "PASSIVE",
                        "score": 5.0,
                        "user_image": {
                          "entities": [
                            {
                              "age": 25.0,
                              "bbox": [
                                40,
                                40,
                                100,
                                100
                              ],
                              "confidence": 0.7177750468254089,
                              "gender": "male"
                            }
                          ],
                          "best_angle": 0
                        },
                        "age_estimation": 25.0,
                        "warnings": [
                          {
                            "risk": "LOW_LIVENESS_SCORE",
                            "feature": "LIVENESS",
                            "additional_data": null,
                            "log_type": "error",
                            "short_description": "Low liveness score",
                            "long_description": "The liveness check resulted in a low score, indicating potential use of non-live facial representations or poor-quality biometric data."
                          }
                        ]
                      },
                      "vendor_data": "user-123",
                      "metadata": null,
                      "created_at": "2026-06-12T02:27:02.901547+00:00"
                    }
                  }
                },
                "schema": {
                  "type": "object",
                  "properties": {
                    "request_id": {
                      "type": "string",
                      "format": "uuid",
                      "description": "ID sesi yang disimpan saat `save_api_request=true` (dapat digunakan dengan `GET /v3/session/{sessionId}/decision/`); jika tidak, berupa UUID korelasi sementara."
                    },
                    "age_estimation": {
                      "type": "object",
                      "properties": {
                        "status": {
                          "type": "string",
                          "enum": [
                            "Approved",
                            "Declined"
                          ],
                          "description": "`Approved` saat tidak ada peringatan yang dimunculkan; jika tidak `Declined` (setiap peringatan yang dihasilkan endpoint ini berujung pada penolakan)."
                        },
                        "method": {
                          "type": "string",
                          "enum": [
                            "PASSIVE"
                          ],
                          "description": "Metode liveness. Selalu `PASSIVE` pada endpoint ini (gambar tunggal, tanpa tantangan pengguna)."
                        },
                        "score": {
                          "type": "number",
                          "format": "float",
                          "nullable": true,
                          "minimum": 0,
                          "maximum": 100,
                          "description": "Skor liveness pasif dari 0 hingga 100 — tingkat keyakinan model bahwa foto menampilkan orang sungguhan. Dibandingkan dengan `face_liveness_score_decline_threshold`; jika bernilai sama atau di bawahnya, panggilan ditolak dengan `LOW_LIVENESS_SCORE`. Bernilai `null` jika model liveness tidak mengembalikan keyakinan — panggilan tetap ditolak dengan `LOW_LIVENESS_SCORE` karena null dianggap sebagai 0 untuk perbandingan ambang batas.",
                          "example": 97.5
                        },
                        "user_image": {
                          "type": "object",
                          "description": "Hasil deteksi wajah untuk gambar yang dianalisis.",
                          "properties": {
                            "entities": {
                              "type": "array",
                              "description": "Satu entri per wajah yang terdeteksi. Kosong jika tidak ada wajah yang ditemukan (maka `age_estimation` bernilai `null` dan peringatan `AGE_NOT_DETECTED` ditambahkan).",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "age": {
                                    "type": "number",
                                    "format": "float",
                                    "description": "Usia wajah ini yang diestimasi oleh model, dalam tahun.",
                                    "example": 27.33
                                  },
                                  "bbox": {
                                    "type": "array",
                                    "items": {
                                      "type": "integer"
                                    },
                                    "minItems": 4,
                                    "maxItems": 4,
                                    "description": "Bounding box wajah yang terdeteksi sebagai koordinat piksel `[x_min, y_min, x_max, y_max]` pada gambar yang diproses.",
                                    "example": [
                                      40,
                                      40,
                                      100,
                                      100
                                    ]
                                  },
                                  "confidence": {
                                    "type": "number",
                                    "format": "float",
                                    "minimum": 0,
                                    "maximum": 1,
                                    "description": "Skor keyakinan deteksi wajah (0–1).",
                                    "example": 0.7177750468254089
                                  },
                                  "gender": {
                                    "type": "string",
                                    "description": "Jenis kelamin yang diprediksi oleh model dari wajah yang terdeteksi (`male` atau `female`). Hanya bersifat informasi.",
                                    "example": "male"
                                  }
                                }
                              }
                            },
                            "best_angle": {
                              "type": "integer",
                              "nullable": true,
                              "description": "Rotasi (derajat: 0, 90, 180, atau 270) yang menghasilkan deteksi wajah terbaik. Hanya bernilai bukan nol jika `rotate_image=true` mengoreksi orientasi.",
                              "example": 0
                            }
                          }
                        },
                        "age_estimation": {
                          "type": "number",
                          "format": "float",
                          "nullable": true,
                          "description": "Usia yang diprediksi model, dalam tahun, dari wajah terdeteksi yang **terbesar**. `null` jika tidak ada usia wajah yang dapat diestimasi (peringatan `AGE_NOT_DETECTED` ditambahkan dan panggilan ditolak).",
                          "example": 27.33
                        },
                        "warnings": {
                          "type": "array",
                          "description": "Kosong jika persetujuan bersih. Entri apa pun akan menetapkan `status` ke `Declined`.",
                          "items": {
                            "type": "object",
                            "properties": {
                              "risk": {
                                "type": "string",
                                "enum": [
                                  "NO_FACE_DETECTED",
                                  "LOW_LIVENESS_SCORE",
                                  "LIVENESS_FACE_ATTACK",
                                  "AGE_NOT_DETECTED",
                                  "AGE_BELOW_MINIMUM"
                                ],
                                "description": "Kode risiko yang dapat dibaca mesin. `NO_FACE_DETECTED` — model liveness tidak menemukan wajah; `LOW_LIVENESS_SCORE` — `score` liveness sama dengan atau di bawah `face_liveness_score_decline_threshold`; `LIVENESS_FACE_ATTACK` — serangan presentasi (foto/layar/topeng) terdeteksi; `AGE_NOT_DETECTED` — usia wajah tidak dapat diestimasi; `AGE_BELOW_MINIMUM` — estimasi usia di bawah `age_estimation_decline_threshold`. `NO_FACE_DETECTED` dan `LOW_LIVENESS_SCORE` bersifat saling eksklusif — saat tidak ada wajah yang ditemukan, hanya `NO_FACE_DETECTED` yang dimunculkan."
                              },
                              "feature": {
                                "type": "string",
                                "enum": [
                                  "LIVENESS"
                                ],
                                "description": "Fitur yang memunculkan peringatan. Selalu `LIVENESS` pada endpoint ini."
                              },
                              "additional_data": {
                                "type": "object",
                                "nullable": true,
                                "additionalProperties": true,
                                "description": "Selalu `null` untuk peringatan estimasi usia."
                              },
                              "log_type": {
                                "type": "string",
                                "enum": [
                                  "error"
                                ],
                                "description": "Tingkat keparahan. Setiap peringatan yang dihasilkan endpoint ini adalah `error` dan mengatur `status` menjadi `Declined`."
                              },
                              "short_description": {
                                "type": "string",
                                "description": "Ringkasan satu baris yang dapat dibaca manusia tentang risiko."
                              },
                              "long_description": {
                                "type": "string",
                                "description": "Penjelasan risiko yang mudah dibaca manusia."
                              }
                            }
                          }
                        }
                      }
                    },
                    "vendor_data": {
                      "type": "string",
                      "nullable": true,
                      "description": "Salinan `vendor_data` yang Anda kirimkan, atau `null`."
                    },
                    "metadata": {
                      "type": "object",
                      "nullable": true,
                      "additionalProperties": true,
                      "description": "Salinan objek `metadata` yang Anda kirimkan, atau `null`."
                    },
                    "created_at": {
                      "type": "string",
                      "format": "date-time",
                      "description": "Stempel waktu ISO 8601 (UTC) saat respons dibuat."
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Kesalahan validasi. Dikembalikan ketika `user_image` tidak ada, melebihi 5 MB, memiliki ekstensi yang tidak didukung, atau ketika ambang batas berada di luar rentang. Isi respons adalah envelope kesalahan kolom standar DRF: satu array pesan per kolom yang bermasalah.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing user image": {
                    "summary": "`user_image` tidak disertakan dalam data formulir",
                    "value": {
                      "user_image": [
                        "No file was submitted."
                      ]
                    }
                  },
                  "Unsupported file extension": {
                    "summary": "Ekstensi file di luar 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": "Unggahan melebihi batas 5 MB",
                    "value": {
                      "user_image": [
                        "File size should not exceed 5 MB"
                      ]
                    }
                  },
                  "Threshold out of range": {
                    "summary": "`face_liveness_score_decline_threshold` di luar rentang 0–100",
                    "value": {
                      "face_liveness_score_decline_threshold": [
                        "Ensure this value is less than or equal to 100."
                      ]
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Izin ditolak. Dikembalikan ketika header `x-api-key` tidak ada, dan juga ketika saldo organisasi pemanggil tidak dapat mencukupi biaya panggilan tersebut; kunci yang salah, dicabut, atau kedaluwarsa mengembalikan `401`. Kunci yang tidak ada mengembalikan `403` dengan `{\"detail\": ...}`; kunci yang salah, dicabut, atau kedaluwarsa mengembalikan `401`. Kekurangan kredit mengembalikan `403` dengan `{\"error\": ...}` sebelum pemrosesan gambar apa pun terjadi.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing or invalid API key": {
                    "summary": "Tidak ada header `x-api-key`, atau kuncinya tidak valid/dicabut",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Not enough credits": {
                    "summary": "Saldo organisasi tidak mencukupi untuk panggilan ini",
                    "value": {
                      "error": "You don't have enough credits to perform this request. Please top up at https://business.didit.me"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Batas laju terlampaui. Endpoint POST/PATCH/DELETE berbagi anggaran 300 permintaan penulisan per menit per kunci API (pembuatan transaksi dan ingesti event memiliki anggaran terpisah sebesar 600). Respons menyertakan header `X-RateLimit-Limit`, `X-RateLimit-Remaining`, `X-RateLimit-Reset`, dan `Retry-After`.",
            "content": {
              "application/json": {
                "examples": {
                  "Write rate limit exceeded": {
                    "summary": "Lebih dari 300 permintaan tulis pada menit ini",
                    "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/age-estimation/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -F 'user_image=@./selfie.jpg' \\\n  -F 'age_estimation_decline_threshold=18' \\\n  -F 'face_liveness_score_decline_threshold=30' \\\n  -F 'save_api_request=true' \\\n  -F 'vendor_data=user-123'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.age_estimation.estimate(\n    user_image=open(\"user_image.jpg\", \"rb\"),\n    face_liveness_score_decline_threshold=30.0,\n    age_estimation_decline_threshold=18,\n    rotate_image=False,\n    save_api_request=True,\n    vendor_data=\"user-123\",\n    metadata={\"flow\": \"age-gate\"},\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit, { fileFromPath } from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.ageEstimation.estimate({\n  user_image: await fileFromPath(\"user_image.jpg\"),\n  face_liveness_score_decline_threshold: 30.0,\n  age_estimation_decline_threshold: 18,\n  rotate_image: false,\n  save_api_request: true,\n  vendor_data: \"user-123\",\n  metadata: { flow: \"age-gate\" },\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.AgeEstimation.Estimate(ctx, didit.AgeEstimationEstimateParams{\n\tUserImage:                         didit.FileFromPath(\"user_image.jpg\"),\n\tFaceLivenessScoreDeclineThreshold: didit.Float(30.0),\n\tAgeEstimationDeclineThreshold:     didit.Int(18),\n\tRotateImage:                       didit.Bool(false),\n\tSaveAPIRequest:                    didit.Bool(true),\n\tVendorData:                        didit.String(\"user-123\"),\n\tMetadata:                          didit.Some(map[string]any{\"flow\": \"age-gate\"}),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.nio.file.Path;\nimport java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.AgeEstimationEstimateParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.ageEstimation().estimate(AgeEstimationEstimateParams.builder()\n        .userImage(Path.of(\"user_image.jpg\"))\n        .faceLivenessScoreDeclineThreshold(30.0)\n        .ageEstimationDeclineThreshold(18L)\n        .rotateImage(false)\n        .saveApiRequest(true)\n        .vendorData(\"user-123\")\n        .metadata(Map.of(\"flow\", \"age-gate\"))\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\nuse Didit\\File;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->ageEstimation->estimate([\n    'user_image' => File::fromPath('user_image.jpg'),\n    'face_liveness_score_decline_threshold' => 30.0,\n    'age_estimation_decline_threshold' => 18,\n    'rotate_image' => false,\n    'save_api_request' => true,\n    'vendor_data' => 'user-123',\n    'metadata' => ['flow' => 'age-gate'],\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.age_estimation.estimate(\n  user_image: Pathname(\"user_image.jpg\"),\n  face_liveness_score_decline_threshold: 30.0,\n  age_estimation_decline_threshold: 18,\n  rotate_image: false,\n  save_api_request: true,\n  vendor_data: \"user-123\",\n  metadata: { flow: \"age-gate\" }\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.AgeEstimation.EstimateAsync(new AgeEstimationEstimateParams\n{\n    UserImage = FileUpload.FromPath(\"user_image.jpg\"),\n    FaceLivenessScoreDeclineThreshold = 30.0,\n    AgeEstimationDeclineThreshold = 18,\n    RotateImage = false,\n    SaveApiRequest = true,\n    VendorData = \"user-123\",\n    Metadata = new Dictionary<string, object> { [\"flow\"] = \"age-gate\" },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/poa/": {
      "post": {
        "summary": "Bukti Alamat (OCR dokumen + pemeriksaan alamat)",
        "description": "Ekstrak dan validasi dokumen Bukti Alamat — tagihan utilitas, rekening koran, dan dokumen yang diterbitkan pemerintah — dalam satu panggilan. Mengembalikan penerbit, tanggal penerbitan/kedaluwarsa, nama pemegang, alamat mentah dan yang telah diurai/digeocoding, `status` `Approved`/`Declined`, serta daftar `warnings` yang menjelaskan setiap masalah yang ditemukan.\n\n**Latensi.** Ekstraksi berbasis LLM: panggilan umum memerlukan waktu **5–15 detik**, PDF multi-halaman hingga **~30 detik**. Konfigurasikan batas waktu klien **setidaknya 45 detik** dan jangan coba lagi sebelum panggilan selesai.\n\n**Cara kerjanya.** Dokumen (gambar atau PDF, hingga 15 MB; PDF terenkripsi memerlukan `document_password`) diklasifikasikan ke dalam tipe dan subtipe dokumen (misalnya `UTILITY_BILL` / `WATER_BILL`), dan penerbit, tanggal, nama pemegang, serta alamat diekstrak menggunakan ekstraksi berbasis LLM. Alamat diurai dan digeocoding ke dalam `poa_parsed_address`. Forensik PDF/EXIF memindai adanya manipulasi — modifikasi setelah penandatanganan digital, editor PDF yang dikenal, manipulasi teks overlay, ekspor ulang yang mencurigakan — yang memunculkan `SUSPECTED_DOCUMENT_MANIPULATION` atau `DOCUMENT_METADATA_MISMATCH`. Kolom teks yang dikosongkan dan diketik ulang dengan font lain, saat file itu sendiri tidak memuat bukti apakah isinya berubah, akan memunculkan `POA_DOCUMENT_UNPROVEN_TEXT_REPLACEMENT`. Usia dokumen divalidasi terhadap `poa_document_age_months`, dan bahasa terhadap `poa_languages_allowed`. Jika Anda meneruskan `expected_address`, `expected_country`, atau `expected_first_name`/`expected_last_name`, nilai yang diekstrak akan diperiksa silang dan ketidakcocokan akan ditandai.\n\n**Logika keputusan.** `status` adalah `Approved` kecuali jika setidaknya satu peringatan berujung pada penolakan. Kegagalan mutlak selalu menghasilkan penolakan: `MISSING_ADDRESS_INFORMATION`, `POA_DOCUMENT_EXPIRED`, `INVALID_DOCUMENT_TYPE`, `UNABLE_TO_VALIDATE_DOCUMENT_AGE`, ditambah `UNABLE_TO_EXTRACT_ISSUE_DATE` dan `POA_NAME_NOT_DETECTED` (tidak dapat dikonfigurasi pada endpoint ini). Lima grup risiko dapat dikonfigurasi per permintaan melalui opsi `poa_*_action` (`DECLINE` atau `NO_ACTION`, semuanya secara default bernilai `DECLINE`). `POA_DOCUMENT_NOT_SUPPORTED_FOR_APPLICATION` dan `UNPARSABLE_OR_INVALID_ADDRESS` bersifat informasional pada endpoint ini dan tidak pernah menghasilkan penolakan. Dokumen yang tidak dapat diproses sama sekali akan mengembalikan `400`; dokumen yang dapat dibaca tetapi bermasalah akan mengembalikan `200` dengan `status: \"Declined\"` — selalu periksa `poa.status` dan `poa.warnings`, bukan hanya kode HTTP.\n\n**Penagihan.** Setiap respons `200` menggunakan satu kredit API Bukti Alamat (dibayar dari kredit paket atau saldo isi saldo Anda). Jika saldo organisasi tidak dapat mencukupi panggilan, endpoint akan mengembalikan `403` dengan kesalahan kredit tidak mencukupi sebelum pemrosesan dokumen apa pun dilakukan.\n\n**Persistensi sesi (`save_api_request`, default `true`).** Jika `true`, panggilan akan disimpan sebagai sesi bertipe API: sesi ini muncul di Business Console, dokumen yang diunggah akan disimpan, `request_id` yang dikembalikan adalah id sesi nyata yang dapat Anda teruskan ke `GET /v3/session/{sessionId}/decision/` (keputusan tersebut juga menampilkan `document_file` dan forensik `document_metadata`, yang ditiadakan dalam respons ini), dan webhook `status.updated` akan dikirimkan. Jika `false`, tidak ada yang disimpan dan `request_id` adalah UUID korelasi sekali pakai yang tidak dapat dicari nantinya.\n\n**Sandbox.** Kunci API sandbox melewati semua pemrosesan dan penagihan: setelah validasi permintaan (input yang salah format tetap mengembalikan `400`), endpoint akan mengembalikan payload tiruan `Approved` statis (tagihan listrik fiktif \"Sandbox Power Co.\"), tidak ada sesi yang disimpan, dan tidak ada kredit yang digunakan.\n\n**Autentikasi.** Kirim kunci API aplikasi Anda di header `x-api-key`. Kredensial yang hilang atau tidak valid akan mengembalikan `403` (`{\"detail\": \"You do not have permission to perform this action.\"}`) — API ini tidak pernah mengembalikan `401`.\n\n**Batas laju.** Kuota penulisan bersama sebesar 300 permintaan/menit per kunci API di seluruh endpoint POST/PATCH/DELETE; melebihi batas ini akan mengembalikan `429`.\n\nCatatan: `FUTURE_ISSUE_DATE` dan `POOR_DOCUMENT_QUALITY` ada dalam sesi alur kerja tetapi tidak pernah dihasilkan oleh endpoint mandiri ini — dokumen bertanggal masa depan tidak ditolak secara otomatis di sini.",
        "operationId": "post_v3poa",
        "x-didit-sdk": {
          "resource": "proof_of_address",
          "method": "verify",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Standalone APIs"
        ],
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "required": [
                  "document"
                ],
                "properties": {
                  "document": {
                    "type": "string",
                    "format": "binary",
                    "description": "Dokumen Bukti Alamat. Ekstensi yang diizinkan: `tiff`, `jpg`, `jpeg`, `png`, `pdf`, `webp`. Ukuran unggahan maksimum: **15 MB** (file yang lebih besar akan ditolak dengan `400`). PDF multi-halaman didukung (perkirakan latensi lebih tinggi); PDF terenkripsi memerlukan `document_password`. Gambar dikompresi secara otomatis sebelum diproses."
                  },
                  "document_password": {
                    "type": "string",
                    "description": "Kata sandi untuk mendekripsi `document` jika berupa PDF terenkripsi. Mengirimkan PDF terenkripsi tanpa kata sandi (atau dengan kata sandi yang salah) mengembalikan `400`.",
                    "writeOnly": true
                  },
                  "expected_address": {
                    "type": "string",
                    "description": "Alamat yang akan diverifikasi terhadap dokumen. Alamat ini di-geocode dan dibandingkan dengan alamat yang diekstrak; ketidakcocokan (atau alamat yang diharapkan tidak dapat di-geocode/diverifikasi) menambahkan `ADDRESS_MISMATCH_WITH_PROVIDED`, yang diatur oleh `poa_address_mismatch_action`. Bentuk yang di-geocode ditampilkan kembali di `expected_details_formatted_address` / `expected_details_parsed_address`.",
                    "example": "Av. Monseñor Tavella 1291, Salta, Argentina"
                  },
                  "expected_country": {
                    "type": "string",
                    "description": "Negara yang akan diverifikasi terhadap dokumen (kode ISO 3166-1, misalnya `ARG` atau `AR`). Ketidakcocokan dengan negara dokumen menambahkan `POA_COUNTRY_MISMATCH_WITH_PROVIDED`, yang diatur oleh `poa_address_mismatch_action`.",
                    "example": "ARG"
                  },
                  "expected_first_name": {
                    "type": "string",
                    "description": "Nama depan untuk diverifikasi terhadap `name_on_document` (pencocokan samar, mendukung transliterasi). Skor di bawah ambang batas kecocokan menambahkan `NAME_MISMATCH_WITH_PROVIDED`, yang diatur oleh `poa_address_mismatch_action`.",
                    "example": "Sophia"
                  },
                  "expected_last_name": {
                    "type": "string",
                    "description": "Nama belakang untuk diverifikasi terhadap `name_on_document`, digabungkan dengan `expected_first_name` untuk skor kecocokan.",
                    "example": "Martinez"
                  },
                  "poa_languages_allowed": {
                    "type": "string",
                    "description": "Daftar bahasa dokumen yang diterima yang dipisahkan koma sebagai kode ISO 639-1 (misalnya `en,es,fr`). Jika dihilangkan atau kosong, **seluruh 51 bahasa yang didukung** akan diterima. Dokumen dalam bahasa di luar daftar akan menambahkan `UNSUPPORTED_DOCUMENT_LANGUAGE` (diatur oleh `poa_unsupported_language_action`); kode yang tidak dikenal dalam daftar akan mengembalikan `400` beserta seluruh kode yang didukung.",
                    "example": "en,es"
                  },
                  "poa_document_age_months": {
                    "type": "string",
                    "description": "Pasangan `key:value` yang dipisahkan koma yang menetapkan usia dokumen maksimum dalam hitungan bulan per jenis dokumen — kunci: `utility_bill`, `bank_statement`, `government_issued_document`, `other_poa_document`; nilai: `1`–`120`, atau `-1` untuk tanpa batas (tanpa pemeriksaan usia). Nilai default jika dihilangkan: `utility_bill:3,bank_statement:3,government_issued_document:12,other_poa_document:12`. Dokumen yang lebih lama dari batasnya akan ditolak dengan `POA_DOCUMENT_EXPIRED`. **Perhatian:** saat Anda memberikan kolom ini, cantumkan *setiap* jenis yang Anda terima — jenis yang dihilangkan akan dianggap tidak diterima (`POA_DOCUMENT_NOT_SUPPORTED_FOR_APPLICATION` bersifat informasi) dan pemeriksaan usianya dilewati.",
                    "example": "utility_bill:3,bank_statement:6"
                  },
                  "poa_name_mismatch_action": {
                    "type": "string",
                    "enum": [
                      "DECLINE",
                      "NO_ACTION"
                    ],
                    "default": "DECLINE",
                    "description": "Diterima tetapi **saat ini tidak diterapkan** — peringatan ketidakcocokan nama (`NAME_MISMATCH_WITH_PROVIDED`) mengikuti `poa_address_mismatch_action`. Atur `poa_address_mismatch_action` untuk mengontrol perilaku ketidakcocokan nama maupun alamat."
                  },
                  "poa_document_issues_action": {
                    "type": "string",
                    "enum": [
                      "DECLINE",
                      "NO_ACTION"
                    ],
                    "default": "DECLINE",
                    "description": "Tindakan yang diambil saat terjadi masalah integritas file — dalam praktiknya hanya `DOCUMENT_METADATA_MISMATCH` yang dihasilkan oleh endpoint ini."
                  },
                  "poa_document_authenticity_action": {
                    "type": "string",
                    "enum": [
                      "DECLINE",
                      "NO_ACTION"
                    ],
                    "default": "DECLINE",
                    "description": "Tindakan yang diambil saat manipulasi dokumen dicurigai (`SUSPECTED_DOCUMENT_MANIPULATION`) — misalnya PDF dimodifikasi setelah penandatanganan digital, diproses oleh editor PDF yang dikenal, menunjukkan manipulasi overlay teks, atau memiliki tanggal EXIF yang tidak konsisten. Opsi ini juga mengatur `POA_DOCUMENT_UNPROVEN_TEXT_REPLACEMENT` (kolom teks yang diketik ulang yang tidak dapat dibuktikan oleh file apakah telah diubah atau tidak): `DECLINE` juga akan menolaknya, `NO_ACTION` menyimpannya sebagai peringatan."
                  },
                  "poa_unsupported_language_action": {
                    "type": "string",
                    "enum": [
                      "DECLINE",
                      "NO_ACTION"
                    ],
                    "default": "DECLINE",
                    "description": "Tindakan yang harus diambil ketika bahasa dokumen berada di luar `poa_languages_allowed` (`UNSUPPORTED_DOCUMENT_LANGUAGE`)."
                  },
                  "poa_address_mismatch_action": {
                    "type": "string",
                    "enum": [
                      "DECLINE",
                      "NO_ACTION"
                    ],
                    "default": "DECLINE",
                    "description": "Tindakan yang harus diambil ketika detail yang diekstrak tidak cocok dengan kolom `expected_*`: `ADDRESS_MISMATCH_WITH_PROVIDED`, `NAME_MISMATCH_WITH_PROVIDED`, dan `POA_COUNTRY_MISMATCH_WITH_PROVIDED` semuanya mengikuti tindakan ini."
                  },
                  "poa_issuer_not_identified_action": {
                    "type": "string",
                    "enum": [
                      "DECLINE",
                      "NO_ACTION"
                    ],
                    "default": "DECLINE",
                    "description": "Tindakan yang diambil saat tidak ada perusahaan/organisasi penerbit yang dapat diidentifikasi pada dokumen (`ISSUER_NOT_IDENTIFIED`)."
                  },
                  "save_api_request": {
                    "type": "boolean",
                    "default": true,
                    "description": "Jika `true` (default), menyimpan panggilan sebagai sesi tipe API — terlihat di Business Console, dapat diambil melalui `GET /v3/session/{sessionId}/decision/` menggunakan `request_id` yang dikembalikan, diumumkan melalui webhook `status.updated`, dan dengan dokumen yang diunggah disimpan. Jika `false`, tidak ada yang disimpan dan `request_id` adalah UUID sementara hanya untuk korelasi respons.",
                    "example": true
                  },
                  "vendor_data": {
                    "type": "string",
                    "description": "String buram opsional (ID pengguna internal, email, UUID Anda…) yang disimpan pada sesi yang dipertahankan dan dikembalikan dalam respons. Gunakan untuk mengorelasikan panggilan API dengan catatan Anda sendiri dan memfilter sesi nantinya.",
                    "example": "user-123"
                  },
                  "metadata": {
                    "type": "object",
                    "additionalProperties": true,
                    "description": "Objek JSON opsional yang disimpan bersama sesi (saat `save_api_request=true`) dan dikembalikan dalam respons. Dalam permintaan multipart, kirimkan sebagai kolom string yang dikodekan dalam JSON (misalnya `metadata={\"flow\":\"onboarding\"}`) — kolom ini akan diuraikan menjadi sebuah objek.",
                    "example": {
                      "flow": "onboarding"
                    }
                  }
                }
              },
              "example": {
                "document": "(binary JPEG/PNG/PDF of the utility bill or bank statement)",
                "expected_address": "Av. Monseñor Tavella 1291, Salta, Argentina",
                "expected_country": "ARG",
                "expected_first_name": "Sophia",
                "expected_last_name": "Martinez",
                "poa_languages_allowed": "en,es",
                "save_api_request": true,
                "vendor_data": "user-123"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Dokumen diproses. `poa.status` bernilai `Approved` atau `Declined`; setiap masalah yang terdeteksi dirinci dalam `poa.warnings`. Dokumen yang kedaluwarsa, tidak cocok, atau mencurigakan tetap menghasilkan `200` dengan `status: \"Declined\"` — periksa isi respons, bukan hanya kode HTTP. Ketika `save_api_request=true`, `request_id` adalah id sesi yang disimpan.",
            "content": {
              "application/json": {
                "examples": {
                  "Approved": {
                    "summary": "Tagihan utilitas dibaca dengan jelas, tanpa pemeriksaan detail yang diharapkan",
                    "value": {
                      "request_id": "4b523a8d-ed32-45e4-8aa8-a89eda459d88",
                      "poa": {
                        "issuing_state": "ARG",
                        "document_type": "UTILITY_BILL",
                        "document_subtype": "WATER_BILL",
                        "document_language": "es",
                        "issuer": "Aguas del Norte",
                        "issue_date": "2026-04-10",
                        "expiration_date": null,
                        "poa_address": "AVDA. MONSEÑOR TAVELLA N° 1291, B° VILLA LAVALLE CP: 4400, CAPITAL - SALTA",
                        "poa_formatted_address": "Av. Monseñor Tavella 1291 b, A4400 Salta, Argentina",
                        "poa_parsed_address": {
                          "street_1": "Avenida Monseñor Tavella 1291",
                          "street_2": "b",
                          "city": "Salta",
                          "region": "Salta",
                          "country": "AR",
                          "postal_code": "A4400",
                          "document_location": {
                            "latitude": -24.8208682,
                            "longitude": -65.4130954
                          }
                        },
                        "expected_details_address": null,
                        "expected_details_formatted_address": null,
                        "expected_details_parsed_address": null,
                        "name_on_document": "OESTE EMBOTELLADORA S.A.",
                        "extra_fields": {
                          "bank_account_number": null,
                          "bank_iban": null,
                          "bank_sort_code": null,
                          "bank_routing_number": null,
                          "bank_swift_bic": null,
                          "bank_branch_name": null,
                          "bank_branch_address": null,
                          "document_phone_number": null,
                          "additional_names": [
                            "LA EMBOTELLADORA DEL NORTE SA"
                          ]
                        },
                        "detected_codes": [
                          {
                            "type": "QR_CODE",
                            "page_number": 1,
                            "position": [
                              [
                                820,
                                1120
                              ],
                              [
                                1002,
                                1120
                              ],
                              [
                                1002,
                                1302
                              ],
                              [
                                820,
                                1302
                              ]
                            ],
                            "x": 820,
                            "y": 1120,
                            "width": 182,
                            "height": 182,
                            "page_width": 1190,
                            "page_height": 1684,
                            "raw_payload": "aHR0cHM6Ly9hZ3Vhc2RlbG5vcnRlLmNvbS9mYWN0dXJhLzk5ODgxMQ==",
                            "parsed_payload": "https://aguasdelnorte.com/factura/998811"
                          },
                          {
                            "type": "CODE_128",
                            "page_number": 1,
                            "position": [
                              [
                                112,
                                1480
                              ],
                              [
                                560,
                                1480
                              ],
                              [
                                560,
                                1540
                              ],
                              [
                                112,
                                1540
                              ]
                            ],
                            "x": 112,
                            "y": 1480,
                            "width": 448,
                            "height": 60,
                            "page_width": 1190,
                            "page_height": 1684,
                            "raw_payload": "MDA5OTg4MTEwMDA0Mg==",
                            "parsed_payload": "0099881100042"
                          }
                        ],
                        "status": "Approved",
                        "warnings": []
                      },
                      "vendor_data": "user-123",
                      "metadata": null,
                      "created_at": "2026-06-12T02:29:02.439655+00:00"
                    }
                  },
                  "Declined - document too old": {
                    "summary": "Tanggal penerbitan lebih lama dari `poa_document_age_months` yang diizinkan",
                    "value": {
                      "request_id": "f61681b8-9422-4378-ac3e-04c6a247fb45",
                      "poa": {
                        "issuing_state": "ARG",
                        "document_type": "UTILITY_BILL",
                        "document_subtype": "WATER_BILL",
                        "document_language": "es",
                        "issuer": "Aguas del Norte",
                        "issue_date": "2021-02-10",
                        "expiration_date": null,
                        "poa_address": "AVDA. MONSEÑOR TAVELLA N° 1291, B° VILLA LAVALLE CP: 4400, CAPITAL - SALTA",
                        "poa_formatted_address": "Av. Monseñor Tavella 1291 b, A4400 Salta, Argentina",
                        "poa_parsed_address": {
                          "street_1": "Avenida Monseñor Tavella 1291",
                          "street_2": "b",
                          "city": "Salta",
                          "region": "Salta",
                          "country": "AR",
                          "postal_code": "A4400",
                          "document_location": {
                            "latitude": -24.8208682,
                            "longitude": -65.4130954
                          }
                        },
                        "expected_details_address": null,
                        "expected_details_formatted_address": null,
                        "expected_details_parsed_address": null,
                        "name_on_document": "OESTE EMBOTELLADORA S.A.",
                        "extra_fields": {
                          "bank_account_number": null,
                          "bank_iban": null,
                          "bank_sort_code": null,
                          "bank_routing_number": null,
                          "bank_swift_bic": null,
                          "bank_branch_name": null,
                          "bank_branch_address": null,
                          "document_phone_number": null,
                          "additional_names": [
                            "LA EMBOTELLADORA DEL NORTE SA"
                          ]
                        },
                        "status": "Declined",
                        "warnings": [
                          {
                            "risk": "POA_DOCUMENT_EXPIRED",
                            "feature": "PROOF_OF_ADDRESS",
                            "additional_data": {
                              "expiration_reason": "age_window",
                              "max_age_months": 3,
                              "document_subtype": "WATER_BILL",
                              "document_type": "UTILITY_BILL",
                              "issue_date": "2021-02-10"
                            },
                            "log_type": "error",
                            "short_description": "Document expired",
                            "long_description": "The submitted document is older than the maximum accepted age of 3 months from its issue date, which exceeds the acceptable time period for validity."
                          }
                        ]
                      },
                      "vendor_data": "user-123",
                      "metadata": null,
                      "created_at": "2026-06-12T02:23:02.165493+00:00"
                    }
                  },
                  "Declined - name mismatch": {
                    "summary": "`expected_first_name`/`expected_last_name` tidak cocok dengan `name_on_document`",
                    "value": {
                      "request_id": "0a7f2f9c-58f1-4b8e-b1e3-2f6f9d4f7a21",
                      "poa": {
                        "issuing_state": "ARG",
                        "document_type": "UTILITY_BILL",
                        "document_subtype": "WATER_BILL",
                        "document_language": "es",
                        "issuer": "Aguas del Norte",
                        "issue_date": "2021-02-10",
                        "expiration_date": null,
                        "poa_address": "AVDA. MONSEÑOR TAVELLA N° 1291, B° VILLA LAVALLE CP: 4400, CAPITAL - SALTA",
                        "poa_formatted_address": "Av. Monseñor Tavella 1291 b, A4400 Salta, Argentina",
                        "poa_parsed_address": {
                          "street_1": "Avenida Monseñor Tavella 1291",
                          "street_2": "b",
                          "city": "Salta",
                          "region": "Salta",
                          "country": "AR",
                          "postal_code": "A4400",
                          "document_location": {
                            "latitude": -24.8208682,
                            "longitude": -65.4130954
                          }
                        },
                        "expected_details_address": null,
                        "expected_details_formatted_address": null,
                        "expected_details_parsed_address": null,
                        "name_on_document": "OESTE EMBOTELLADORA S.A.",
                        "extra_fields": {
                          "bank_account_number": null,
                          "bank_iban": null,
                          "bank_sort_code": null,
                          "bank_routing_number": null,
                          "bank_swift_bic": null,
                          "bank_branch_name": null,
                          "bank_branch_address": null,
                          "document_phone_number": null,
                          "additional_names": [
                            "LA EMBOTELLADORA DEL NORTE SA"
                          ]
                        },
                        "status": "Declined",
                        "warnings": [
                          {
                            "risk": "NAME_MISMATCH_WITH_PROVIDED",
                            "feature": "PROOF_OF_ADDRESS",
                            "additional_data": null,
                            "log_type": "error",
                            "short_description": "Name mismatch with provided information",
                            "long_description": "The full name on the document does not match the name from the user's verified identity documents, or the full name sent by API."
                          }
                        ]
                      },
                      "vendor_data": "user-123",
                      "metadata": null,
                      "created_at": "2026-06-12T02:27:21.330172+00:00"
                    }
                  }
                },
                "schema": {
                  "type": "object",
                  "properties": {
                    "request_id": {
                      "type": "string",
                      "format": "uuid",
                      "description": "ID sesi yang disimpan saat `save_api_request=true` (dapat digunakan dengan `GET /v3/session/{sessionId}/decision/`); jika tidak, berupa UUID korelasi sementara."
                    },
                    "poa": {
                      "type": "object",
                      "properties": {
                        "status": {
                          "type": "string",
                          "enum": [
                            "Approved",
                            "Declined"
                          ],
                          "description": "`Approved` saat tidak ada peringatan yang menghasilkan penolakan; jika tidak `Declined` — daftar `warnings` menjelaskan alasannya."
                        },
                        "issuing_state": {
                          "type": "string",
                          "nullable": true,
                          "description": "Negara tempat dokumen diterbitkan, sebagaimana diekstrak dari dokumen — biasanya ISO 3166-1 alpha-3 (misalnya `ARG`).",
                          "example": "ARG"
                        },
                        "document_type": {
                          "type": "string",
                          "enum": [
                            "UTILITY_BILL",
                            "BANK_STATEMENT",
                            "GOVERNMENT_ISSUED_DOCUMENT",
                            "OTHER_POA_DOCUMENT",
                            "UNKNOWN"
                          ],
                          "description": "Kategori dokumen yang terdeteksi. `UNKNOWN` berarti dokumen tidak dapat diklasifikasikan sebagai Bukti Alamat yang dapat diterima dan otomatis ditolak dengan `INVALID_DOCUMENT_TYPE`. Tidak pernah null — kegagalan klasifikasi beralih ke `UNKNOWN`."
                        },
                        "document_subtype": {
                          "type": "string",
                          "description": "Klasifikasi yang lebih terperinci dalam `document_type` — mis. `ELECTRICITY_BILL`, `WATER_BILL`, `GAS_BILL`, `INTERNET_BILL`, `PHONE_BILL` (tagihan utilitas); `ACCOUNT_STATEMENT`, `CREDIT_CARD_STATEMENT` (rekening koran bank); `TAX_ASSESSMENT`, `RESIDENCY_CERTIFICATE` (dokumen pemerintah). `UNKNOWN` jika tidak ada subtipe yang dapat ditentukan. Tidak pernah null — jika klasifikasi gagal, digunakan `UNKNOWN` sebagai fallback.",
                          "example": "WATER_BILL"
                        },
                        "document_language": {
                          "type": "string",
                          "nullable": true,
                          "description": "Bahasa dokumen yang terdeteksi (ISO 639-1).",
                          "example": "es"
                        },
                        "issuer": {
                          "type": "string",
                          "nullable": true,
                          "description": "Perusahaan atau organisasi yang menerbitkan dokumen. `null` menambahkan `ISSUER_NOT_IDENTIFIED`.",
                          "example": "Aguas del Norte"
                        },
                        "issue_date": {
                          "type": "string",
                          "format": "date",
                          "nullable": true,
                          "description": "Tanggal penerbitan dokumen (`YYYY-MM-DD`). `null` jika tidak dapat diekstraksi — kondisi ini menyebabkan permintaan ditolak dengan `UNABLE_TO_EXTRACT_ISSUE_DATE` pada endpoint ini.",
                          "example": "2021-02-10"
                        },
                        "expiration_date": {
                          "type": "string",
                          "format": "date",
                          "nullable": true,
                          "description": "Tanggal kedaluwarsa/masa berlaku eksplisit yang tertera pada dokumen, jika ada. Tidak bergantung pada pemeriksaan usia dokumen `poa_document_age_months`."
                        },
                        "poa_address": {
                          "type": "string",
                          "nullable": true,
                          "description": "Alamat persis seperti yang tertera pada dokumen. `null` otomatis ditolak dengan `MISSING_ADDRESS_INFORMATION`."
                        },
                        "poa_formatted_address": {
                          "type": "string",
                          "nullable": true,
                          "description": "Versi yang telah dinormalisasi dan di-geocode dari `poa_address`.",
                          "example": "Av. Monseñor Tavella 1291 b, A4400 Salta, Argentina"
                        },
                        "poa_parsed_address": {
                          "type": "object",
                          "nullable": true,
                          "description": "Rincian terstruktur dan telah diberi geocode dari alamat dokumen. `null` jika alamat tidak dapat diurai.",
                          "properties": {
                            "street_1": {
                              "type": "string",
                              "nullable": true,
                              "example": "Avenida Monseñor Tavella 1291"
                            },
                            "street_2": {
                              "type": "string",
                              "nullable": true
                            },
                            "city": {
                              "type": "string",
                              "nullable": true,
                              "example": "Salta"
                            },
                            "region": {
                              "type": "string",
                              "nullable": true,
                              "example": "Salta"
                            },
                            "country": {
                              "type": "string",
                              "nullable": true,
                              "description": "Kode negara ISO 3166-1 alpha-2.",
                              "example": "AR"
                            },
                            "postal_code": {
                              "type": "string",
                              "nullable": true,
                              "example": "A4400"
                            },
                            "document_location": {
                              "type": "object",
                              "nullable": true,
                              "properties": {
                                "latitude": {
                                  "type": "number"
                                },
                                "longitude": {
                                  "type": "number"
                                }
                              },
                              "description": "Koordinat hasil geocoding dari alamat dokumen."
                            }
                          }
                        },
                        "expected_details_address": {
                          "type": "string",
                          "nullable": true,
                          "description": "Salinan `expected_address` yang Anda kirimkan, atau `null`."
                        },
                        "expected_details_formatted_address": {
                          "type": "string",
                          "nullable": true,
                          "description": "Versi `expected_address` yang dinormalisasi dan di-geocode; bernilai `null` jika tidak disediakan atau tidak dapat di-geocode."
                        },
                        "expected_details_parsed_address": {
                          "type": "object",
                          "nullable": true,
                          "additionalProperties": true,
                          "description": "Hasil geocoding lengkap untuk `expected_address` (jalan/kota/wilayah/negara/kode pos ditambah output geocoder mentah dan tanda `is_verified`). Bernilai `null` jika `expected_address` tidak diberikan."
                        },
                        "name_on_document": {
                          "type": "string",
                          "nullable": true,
                          "description": "Nama pemegang utama yang diekstrak dari dokumen; dibandingkan dengan `expected_first_name`/`expected_last_name` jika diberikan. `null` akan ditolak dengan `POA_NAME_NOT_DETECTED` pada endpoint ini.",
                          "example": "OESTE EMBOTELLADORA S.A."
                        },
                        "extra_fields": {
                          "type": "object",
                          "description": "Tambahan khusus dokumen. Kolom bank diisi untuk rekening koran jika tercetak pada dokumen; `null` jika tidak.",
                          "properties": {
                            "bank_account_number": {
                              "type": "string",
                              "nullable": true
                            },
                            "bank_iban": {
                              "type": "string",
                              "nullable": true
                            },
                            "bank_sort_code": {
                              "type": "string",
                              "nullable": true
                            },
                            "bank_routing_number": {
                              "type": "string",
                              "nullable": true
                            },
                            "bank_swift_bic": {
                              "type": "string",
                              "nullable": true
                            },
                            "bank_branch_name": {
                              "type": "string",
                              "nullable": true
                            },
                            "bank_branch_address": {
                              "type": "string",
                              "nullable": true
                            },
                            "document_phone_number": {
                              "type": "string",
                              "nullable": true,
                              "description": "Nomor telepon kontak yang tercetak pada dokumen."
                            },
                            "additional_names": {
                              "type": "array",
                              "items": {
                                "type": "string"
                              },
                              "description": "Nama pemegang lain yang ditemukan pada dokumen (misalnya, pemegang rekening bersama, nama rekening sebelumnya)."
                            }
                          }
                        },
                        "warnings": {
                          "type": "array",
                          "description": "Kosong jika persetujuan bersih. Setiap entri menjelaskan satu risiko yang terdeteksi; entri dengan `log_type: \"error\"` menetapkan `status` ke `Declined`.",
                          "items": {
                            "type": "object",
                            "properties": {
                              "risk": {
                                "type": "string",
                                "description": "Kode risiko yang dapat dibaca mesin. Selalu ditolak: `MISSING_ADDRESS_INFORMATION`, `POA_DOCUMENT_EXPIRED`, `INVALID_DOCUMENT_TYPE`, `UNABLE_TO_VALIDATE_DOCUMENT_AGE`, ditambah `UNABLE_TO_EXTRACT_ISSUE_DATE` dan `POA_NAME_NOT_DETECTED` (ditetapkan untuk ditolak pada endpoint ini). Diatur oleh opsi permintaan: `NAME_MISMATCH_WITH_PROVIDED` / `ADDRESS_MISMATCH_WITH_PROVIDED` / `POA_COUNTRY_MISMATCH_WITH_PROVIDED` (`poa_address_mismatch_action`), `POOR_DOCUMENT_QUALITY` (tidak pernah dihasilkan oleh endpoint ini) / `DOCUMENT_METADATA_MISMATCH` (`poa_document_issues_action`), `SUSPECTED_DOCUMENT_MANIPULATION` dan `POA_DOCUMENT_UNPROVEN_TEXT_REPLACEMENT` (`poa_document_authenticity_action`), `UNSUPPORTED_DOCUMENT_LANGUAGE` (`poa_unsupported_language_action`), `ISSUER_NOT_IDENTIFIED` (`poa_issuer_not_identified_action`). Bersifat informasional pada endpoint ini: `POA_DOCUMENT_NOT_SUPPORTED_FOR_APPLICATION`, `UNPARSABLE_OR_INVALID_ADDRESS`.",
                                "example": "POA_DOCUMENT_EXPIRED"
                              },
                              "feature": {
                                "type": "string",
                                "enum": [
                                  "PROOF_OF_ADDRESS"
                                ],
                                "description": "Fitur yang memunculkan peringatan. Selalu `PROOF_OF_ADDRESS` pada endpoint ini."
                              },
                              "additional_data": {
                                "type": "object",
                                "nullable": true,
                                "additionalProperties": true,
                                "description": "Konteks tambahan untuk beberapa risiko — misalnya `POA_DOCUMENT_EXPIRED` menyertakan `expiration_reason` (`printed_expiration` atau `age_window`), `document_type`, `document_subtype`, dan `issue_date`, ditambah `expiration_date` pada jalur `printed_expiration` atau `max_age_months` pada jalur `age_window`; `SUSPECTED_DOCUMENT_MANIPULATION` menyertakan `reason` dan `detection_method`; `POA_DOCUMENT_UNPROVEN_TEXT_REPLACEMENT` menyertakan `reason`, `detection_method` (`unproven_text_replacement`), `replaced_text`, `manipulated_regions`, dan `manipulated_blocks`. `null` untuk sebagian besar risiko."
                              },
                              "log_type": {
                                "type": "string",
                                "enum": [
                                  "error",
                                  "information"
                                ],
                                "description": "Tingkat keparahan. Peringatan `error` mendorong `status` menjadi `Declined`; entri `information` bersifat anjuran dan tidak pernah menolak dengan sendirinya. (`warning` tidak dihasilkan oleh endpoint ini — opsinya hanya menerima `DECLINE` atau `NO_ACTION`.)"
                              },
                              "short_description": {
                                "type": "string",
                                "description": "Ringkasan satu baris yang dapat dibaca manusia tentang risiko."
                              },
                              "long_description": {
                                "type": "string",
                                "description": "Penjelasan risiko yang mudah dibaca manusia."
                              }
                            }
                          }
                        },
                        "detected_codes": {
                          "type": "array",
                          "description": "Kode QR dan barcode yang terdeteksi di setiap halaman dokumen yang diproses. Kosong jika tidak ada yang ditemukan. Kode QR yang ditemukan namun tidak dapat didekode memiliki `parsed_payload: null`.",
                          "items": {
                            "$ref": "#/components/schemas/DocumentAIDetectedCode"
                          }
                        }
                      }
                    },
                    "vendor_data": {
                      "type": "string",
                      "nullable": true,
                      "description": "Salinan `vendor_data` yang Anda kirimkan, atau `null`."
                    },
                    "metadata": {
                      "type": "object",
                      "nullable": true,
                      "additionalProperties": true,
                      "description": "Salinan objek `metadata` yang Anda kirimkan, atau `null`."
                    },
                    "created_at": {
                      "type": "string",
                      "format": "date-time",
                      "description": "Stempel waktu ISO 8601 (UTC) saat respons dibuat."
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Kesalahan validasi atau pemrosesan. Masalah tingkat kolom mengembalikan envelope standar DRF (satu array pesan per kolom yang bermasalah). Masalah PDF terenkripsi mengembalikan `{\"detail\": ...}`. Dokumen yang tidak dapat diproses oleh pipeline ekstraksi mengembalikan `{\"error\": [\"Error extracting POA information\"]}`.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing document": {
                    "summary": "`document` tidak disertakan dalam data formulir",
                    "value": {
                      "document": [
                        "No file was submitted."
                      ]
                    }
                  },
                  "Unsupported file extension": {
                    "summary": "Ekstensi file di luar tiff/jpg/jpeg/png/pdf/webp",
                    "value": {
                      "document": [
                        "File extension “txt” is not allowed. Allowed extensions are: tiff, jpg, jpeg, png, pdf, webp."
                      ]
                    }
                  },
                  "File too large": {
                    "summary": "Unggahan melebihi batas 15 MB",
                    "value": {
                      "document": [
                        "File size should not exceed 15 MB"
                      ]
                    }
                  },
                  "Encrypted PDF": {
                    "summary": "PDF diunggah tanpa kata sandi yang diperlukan",
                    "value": {
                      "detail": "The PDF is encrypted. Please upload a decrypted PDF or a photo instead."
                    }
                  },
                  "Wrong PDF password": {
                    "summary": "`document_password` tidak dapat mendekripsi PDF",
                    "value": {
                      "detail": "The PDF password is incorrect. Please provide the correct password."
                    }
                  },
                  "Invalid language code": {
                    "summary": "`poa_languages_allowed` memuat kode yang tidak didukung",
                    "value": {
                      "poa_languages_allowed": [
                        "Invalid language code: 'xx'. Must be one of the supported languages: ['ar', 'bn', 'hy', 'bg', 'bs', 'ca', 'cnr', 'sq', 'zh', 'hr', 'cs', 'da', 'nl', 'en', 'et', 'fi', 'fr', 'ka', 'kk', 'de', 'el', 'he', 'hi', 'hu', 'id', 'it', 'ja', 'ko', 'ky', 'lv', 'lt', 'mk', 'mn', 'ms', 'no', 'fa', 'pl', 'pt', 'ro', 'ru', 'sr', 'sk', 'sl', 'so', 'es', 'sv', 'th', 'tr', 'uk', 'uz', 'vi']."
                      ]
                    }
                  },
                  "Invalid document age value": {
                    "summary": "Nilai `poa_document_age_months` berada di luar rentang 1–120 / -1",
                    "value": {
                      "poa_document_age_months": [
                        "Invalid integer value for 'utility_bill': '999'. Must be -1 (unlimited) or a positive integer between 1 and 120."
                      ]
                    }
                  },
                  "Extraction failure": {
                    "summary": "Dokumen tidak dapat diproses oleh pipeline ekstraksi",
                    "value": {
                      "error": [
                        "Error extracting POA information"
                      ]
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Izin ditolak. Dikembalikan ketika header `x-api-key` tidak ada, dan juga ketika saldo organisasi pemanggil tidak dapat mencukupi biaya panggilan tersebut; kunci yang salah, dicabut, atau kedaluwarsa mengembalikan `401`. Kunci yang tidak ada mengembalikan `403` dengan `{\"detail\": ...}`; kunci yang salah, dicabut, atau kedaluwarsa mengembalikan `401`. Kekurangan kredit mengembalikan `403` dengan `{\"error\": ...}` sebelum pemrosesan dokumen apa pun terjadi.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing or invalid API key": {
                    "summary": "Tidak ada header `x-api-key`, atau kuncinya tidak valid/dicabut",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Not enough credits": {
                    "summary": "Saldo organisasi tidak mencukupi untuk panggilan ini",
                    "value": {
                      "error": "You don't have enough credits to perform this request. Please top up at https://business.didit.me"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Batas laju terlampaui. Endpoint POST/PATCH/DELETE berbagi anggaran 300 permintaan penulisan per menit per kunci API (pembuatan transaksi dan ingesti event memiliki anggaran terpisah sebesar 600). Respons menyertakan header `X-RateLimit-Limit`, `X-RateLimit-Remaining`, `X-RateLimit-Reset`, dan `Retry-After`.",
            "content": {
              "application/json": {
                "examples": {
                  "Write rate limit exceeded": {
                    "summary": "Lebih dari 300 permintaan tulis pada menit ini",
                    "value": {
                      "detail": "Write request rate limit exceeded. You can make up to 300 requests per minute."
                    }
                  }
                },
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "503": {
            "$ref": "#/components/responses/DocumentProcessingBusy"
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL",
            "source": "curl -X POST 'https://verification.didit.me/v3/poa/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -F 'document=@./utility-bill.pdf' \\\n  -F 'expected_address=Av. Monseñor Tavella 1291, Salta, Argentina' \\\n  -F 'expected_country=ARG' \\\n  -F 'expected_first_name=Sophia' \\\n  -F 'expected_last_name=Martinez' \\\n  -F 'poa_languages_allowed=en,es' \\\n  -F 'vendor_data=user-123' \\\n  --max-time 45"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.proof_of_address.verify(\n    document=open(\"document.pdf\", \"rb\"),\n    expected_address=\"Av. Monseñor Tavella 1291, Salta, Argentina\",\n    expected_country=\"ARG\",\n    expected_first_name=\"Sophia\",\n    expected_last_name=\"Martinez\",\n    poa_languages_allowed=\"en,es\",\n    save_api_request=True,\n    vendor_data=\"user-123\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit, { fileFromPath } from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.proofOfAddress.verify({\n  document: await fileFromPath(\"document.pdf\"),\n  expected_address: \"Av. Monseñor Tavella 1291, Salta, Argentina\",\n  expected_country: \"ARG\",\n  expected_first_name: \"Sophia\",\n  expected_last_name: \"Martinez\",\n  poa_languages_allowed: \"en,es\",\n  save_api_request: true,\n  vendor_data: \"user-123\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.ProofOfAddress.Verify(ctx, didit.ProofOfAddressVerifyParams{\n\tDocument:            didit.FileFromPath(\"document.pdf\"),\n\tExpectedAddress:     didit.String(\"Av. Monseñor Tavella 1291, Salta, Argentina\"),\n\tExpectedCountry:     didit.String(\"ARG\"),\n\tExpectedFirstName:   didit.String(\"Sophia\"),\n\tExpectedLastName:    didit.String(\"Martinez\"),\n\tPOALanguagesAllowed: didit.String(\"en,es\"),\n\tSaveAPIRequest:      didit.Bool(true),\n\tVendorData:          didit.String(\"user-123\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.nio.file.Path;\nimport me.didit.Didit;\nimport me.didit.types.ProofOfAddressVerifyParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.proofOfAddress().verify(ProofOfAddressVerifyParams.builder()\n        .document(Path.of(\"document.pdf\"))\n        .expectedAddress(\"Av. Monseñor Tavella 1291, Salta, Argentina\")\n        .expectedCountry(\"ARG\")\n        .expectedFirstName(\"Sophia\")\n        .expectedLastName(\"Martinez\")\n        .poaLanguagesAllowed(\"en,es\")\n        .saveApiRequest(true)\n        .vendorData(\"user-123\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\nuse Didit\\File;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->proofOfAddress->verify([\n    'document' => File::fromPath('document.pdf'),\n    'expected_address' => 'Av. Monseñor Tavella 1291, Salta, Argentina',\n    'expected_country' => 'ARG',\n    'expected_first_name' => 'Sophia',\n    'expected_last_name' => 'Martinez',\n    'poa_languages_allowed' => 'en,es',\n    'save_api_request' => true,\n    'vendor_data' => 'user-123',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.proof_of_address.verify(\n  document: Pathname(\"document.pdf\"),\n  expected_address: \"Av. Monseñor Tavella 1291, Salta, Argentina\",\n  expected_country: \"ARG\",\n  expected_first_name: \"Sophia\",\n  expected_last_name: \"Martinez\",\n  poa_languages_allowed: \"en,es\",\n  save_api_request: true,\n  vendor_data: \"user-123\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.ProofOfAddress.VerifyAsync(new ProofOfAddressVerifyParams\n{\n    Document = FileUpload.FromPath(\"document.pdf\"),\n    ExpectedAddress = \"Av. Monseñor Tavella 1291, Salta, Argentina\",\n    ExpectedCountry = \"ARG\",\n    ExpectedFirstName = \"Sophia\",\n    ExpectedLastName = \"Martinez\",\n    PoaLanguagesAllowed = \"en,es\",\n    SaveApiRequest = true,\n    VendorData = \"user-123\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/document-ai/": {
      "post": {
        "summary": "Document AI (ekstraksi kolom kustom + pemeriksaan manipulasi)",
        "description": "Ekstraksi kolom yang **Anda** tentukan dari dokumen pendukung apa pun — slip gaji, bukti dana, surat sumber kekayaan, laporan pajak, kontrak, faktur — dalam satu panggilan. Kirim file beserta definisi `fields` (kunci, nama, instruksi ekstraksi, tipe) dan dapatkan nilai bertipe (`text`, `number`, `date` sebagai `YYYY-MM-DD`), skor kecocokan nama opsional terhadap orang atau perusahaan yang diharapkan, sinyal manipulasi PDF/EXIF, `status` `Approved`/`Declined`/`In Review`, serta daftar `warnings` yang menjelaskan setiap masalah yang ditemukan. Ini adalah padanan server-ke-server dari langkah alur kerja Document AI yang di-hosting (lihat `/core-technology/document-ai/overview`); fitur ini menggunakan model ekstraksi default Didit dan tidak menyediakan pilihan penyedia.\n\n**Latensi.** Ekstraksi berbasis LLM: panggilan tipikal membutuhkan waktu **5–15 detik**, PDF multi-halaman hingga **~30 detik**. Konfigurasikan batas waktu klien **setidaknya 45 detik** dan jangan coba lagi sebelum panggilan selesai.\n\n**Format permintaan.** Hanya `multipart/form-data`. `fields` adalah **satu string array yang dienkode JSON** (1–30 item, maksimal 16 KB); array formulir bergaya kurung siku ditolak dengan `400`. Setiap item adalah `{key, name, instruction, type, required, is_full_name}` — `key` adalah kunci JSON yang Anda dapatkan kembali (`^[a-z0-9_]{1,64}$`, unik), `instruction` memberi tahu model apa yang harus dibaca, `type` adalah `text` (default) | `number` | `date`, `required` memunculkan `DOCUMENT_AI_MISSING_REQUIRED_FIELDS` ketika nilainya tidak dapat dibaca, dan paling banyak satu kolom dapat mengatur `is_full_name: true` untuk menandai nilai yang dibandingkan dengan nama yang diharapkan.\n\n**Pencocokan nama.** Teruskan `expected_first_name` + `expected_last_name` (orang) **atau** `expected_company_name` (+ opsional `expected_company_country`) — jangan keduanya. Nilai dari kolom `is_full_name` (atau, jika tidak ada yang ditandai, kolom teks pertama yang kuncinya menyerupai nama) dibandingkan secara fuzzy; `name_match_score` (0–100) dan `name_on_document` selalu dikembalikan jika kedua belah pihak ada, dan skor di bawah `document_ai_name_match_score_threshold` (default 80) menambahkan `DOCUMENT_AI_NAME_MISMATCH`, yang diatur oleh `document_ai_name_mismatch_action`.\n\n**Logika keputusan.** Setiap risiko dipetakan ke tindakan yang dapat dikonfigurasi: `DECLINE` → `status: \"Declined\"`, `REVIEW` → `status: \"In Review\"`, `NO_ACTION` → hanya bersifat informasi. Nilai default mencerminkan langkah alur kerja: dokumen tidak terbaca `REVIEW`, kolom wajib tidak ada `REVIEW`, dugaan manipulasi `DECLINE`, nama tidak cocok `NO_ACTION`, file tidak didukung `REVIEW`. Dokumen yang sama sekali tidak dapat diproses mengembalikan `400`; dokumen yang dapat dibaca tetapi bermasalah mengembalikan `200` dengan `Declined`/`In Review` — selalu periksa `document_ai.status` dan `document_ai.warnings`, bukan hanya kode HTTP.\n\n**Penagihan.** Setiap respons `200` menggunakan satu kredit API Document AI — **$0.20 per dokumen** berdasarkan tarif standar, dibayar dari kredit paket atau saldo isi saldo Anda. Ketika saldo organisasi tidak dapat menutupi panggilan, endpoint mengembalikan `403` sebelum pemrosesan apa pun dilakukan. Kunci API sandbox mengembalikan respons tiruan deterministik dan tidak dikenai biaya.\n\n**Persistensi.** Dengan `save_api_request=true` (default), panggilan disimpan sebagai sesi bertipe API: dokumen, nilai yang diekstraksi, definisi kolom, dan cuplikan pencocokan nama disimpan, sesi muncul di Business Console, dan `request_id` berfungsi dengan `GET /v3/session/{sessionId}/decision/`.",
        "operationId": "post_v3document-ai",
        "x-didit-sdk": {
          "resource": "document_ai",
          "method": "analyze",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Standalone APIs"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "required": [
                  "document",
                  "fields"
                ],
                "properties": {
                  "document": {
                    "type": "string",
                    "format": "binary",
                    "description": "Dokumen yang akan dibaca. Ekstensi yang diizinkan: `tiff`, `jpg`, `jpeg`, `png`, `pdf`, `webp`, `zip`. Ukuran unggahan maksimum: **30 MB** (berkas yang lebih besar ditolak dengan `400`). PDF beberapa halaman didukung (perkirakan latensi lebih tinggi); PDF terenkripsi ditolak dengan `400`. Gambar dikompresi secara otomatis sebelum diproses."
                  },
                  "fields": {
                    "type": "string",
                    "description": "Satu string array berformat JSON dengan **1–30** definisi kolom (maksimum 16 KB). Setiap item: `key` (wajib, `^[a-z0-9_]{1,64}$`, unik — kunci yang dikembalikan di `extracted_data`), `name` (≤100 karakter, ditampilkan dalam pesan), `instruction` (≤500 karakter, apa yang harus dibaca model), `type` (default `text` | `number` | `date`), `required` (boolean, default `false`), `is_full_name` (boolean, default `false`, paling banyak satu per permintaan). Array form bergaya tanda kurung, JSON tidak valid, kunci duplikat, atau lebih dari satu `is_full_name` akan mengembalikan `400` sebelum pemrosesan atau penagihan apa pun.",
                    "example": "[{\"key\": \"employer_name\", \"name\": \"Employer name\", \"instruction\": \"The employer or company issuing the payslip.\", \"type\": \"text\", \"required\": true, \"is_full_name\": false}, {\"key\": \"employee_name\", \"name\": \"Employee name\", \"instruction\": \"The full name of the employee as printed on the payslip.\", \"type\": \"text\", \"required\": true, \"is_full_name\": true}, {\"key\": \"net_pay\", \"name\": \"Net pay\", \"instruction\": \"The net amount paid to the employee for the period.\", \"type\": \"number\", \"required\": true, \"is_full_name\": false}, {\"key\": \"pay_date\", \"name\": \"Pay date\", \"instruction\": \"The payment date shown on the payslip.\", \"type\": \"date\", \"required\": false, \"is_full_name\": false}]"
                  },
                  "expected_first_name": {
                    "type": "string",
                    "description": "Nama depan untuk diverifikasi terhadap kolom nama dokumen (pencocokan samar, mendukung transliterasi). Gunakan bersama dengan `expected_last_name`; tidak dapat digabungkan dengan `expected_company_name`.",
                    "example": "Sophia"
                  },
                  "expected_last_name": {
                    "type": "string",
                    "description": "Nama belakang untuk diverifikasi terhadap kolom nama dokumen, digabungkan dengan `expected_first_name` untuk `name_match_score`.",
                    "example": "Martinez"
                  },
                  "expected_company_name": {
                    "type": "string",
                    "description": "Nama perusahaan yang akan diverifikasi terhadap kolom nama pada dokumen (untuk dokumen bisnis). Tidak dapat digabungkan dengan `expected_first_name` / `expected_last_name` (sengaja tanpa nilai contoh — sampel permintaan yang dihasilkan menggunakan kolom untuk orang; ganti kolom tersebut dengan kolom ini saat memverifikasi dokumen bisnis)."
                  },
                  "expected_company_country": {
                    "type": "string",
                    "description": "Kode negara ISO 3166-1 alpha-2 opsional (dua huruf ASCII, misalnya `FR`) yang menyesuaikan normalisasi nama perusahaan untuk `expected_company_name`. Hanya digunakan bersama `expected_company_name`."
                  },
                  "document_ai_name_match_score_threshold": {
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 100,
                    "default": 80,
                    "description": "`name_match_score` minimum (0–100) untuk menganggap nama cocok. Skor yang lebih rendah menambahkan `DOCUMENT_AI_NAME_MISMATCH`, yang diatur oleh `document_ai_name_mismatch_action`.",
                    "example": 80
                  },
                  "document_ai_unreadable_document_action": {
                    "type": "string",
                    "enum": [
                      "DECLINE",
                      "REVIEW",
                      "NO_ACTION"
                    ],
                    "default": "REVIEW",
                    "description": "Tindakan yang diambil saat tidak ada kolom yang dapat dibaca dari dokumen (`DOCUMENT_AI_UNREADABLE_DOCUMENT`)."
                  },
                  "document_ai_missing_required_fields_action": {
                    "type": "string",
                    "enum": [
                      "DECLINE",
                      "REVIEW",
                      "NO_ACTION"
                    ],
                    "default": "REVIEW",
                    "description": "Tindakan yang diambil saat setidaknya satu kolom `required` tidak dapat dibaca (`DOCUMENT_AI_MISSING_REQUIRED_FIELDS`; `additional_data.missing_fields` mencantumkannya)."
                  },
                  "document_ai_document_tampering_action": {
                    "type": "string",
                    "enum": [
                      "DECLINE",
                      "REVIEW",
                      "NO_ACTION"
                    ],
                    "default": "DECLINE",
                    "description": "Tindakan yang diambil saat forensik PDF/EXIF mencurigai adanya manipulasi — dimodifikasi setelah penandatanganan digital, editor PDF yang dikenal, manipulasi overlay teks, ekspor ulang yang mencurigakan, anomali gambar (`DOCUMENT_AI_SUSPECTED_MANIPULATION`)."
                  },
                  "document_ai_name_mismatch_action": {
                    "type": "string",
                    "enum": [
                      "DECLINE",
                      "REVIEW",
                      "NO_ACTION"
                    ],
                    "default": "NO_ACTION",
                    "description": "Tindakan yang diambil saat `name_match_score` berada di bawah ambang batas (`DOCUMENT_AI_NAME_MISMATCH`)."
                  },
                  "document_ai_unsupported_file_action": {
                    "type": "string",
                    "enum": [
                      "DECLINE",
                      "REVIEW",
                      "NO_ACTION"
                    ],
                    "default": "REVIEW",
                    "description": "Tindakan yang harus diambil ketika unggahan kosong atau bukan file yang dapat diproses (`DOCUMENT_AI_UNSUPPORTED_FILE`)."
                  },
                  "save_api_request": {
                    "type": "boolean",
                    "default": true,
                    "description": "Jika `true` (default), menyimpan panggilan sebagai sesi tipe API — terlihat di Business Console, dapat diambil melalui `GET /v3/session/{sessionId}/decision/` menggunakan `request_id` yang dikembalikan, dengan dokumen yang diunggah, nilai yang diekstrak, definisi kolom, dan snapshot pencocokan nama yang disimpan. Jika `false`, tidak ada yang disimpan dan `request_id` adalah UUID sementara hanya untuk korelasi respons; panggilan tetap ditagihkan.",
                    "example": true
                  },
                  "vendor_data": {
                    "type": "string",
                    "description": "String buram opsional (ID pengguna internal, email, UUID Anda…) yang disimpan pada sesi yang dipertahankan dan dikembalikan dalam respons. Gunakan untuk mengorelasikan panggilan API dengan catatan Anda sendiri dan memfilter sesi nantinya.",
                    "example": "user-123"
                  },
                  "metadata": {
                    "type": "object",
                    "additionalProperties": true,
                    "description": "Objek JSON opsional yang disimpan bersama sesi (saat `save_api_request=true`) dan dikembalikan dalam respons. Dalam permintaan multipart, kirimkan sebagai kolom string yang dikodekan dalam JSON (misalnya `metadata={\"flow\":\"onboarding\"}`) — kolom ini akan diuraikan menjadi sebuah objek.",
                    "example": {
                      "flow": "onboarding"
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Dokumen diproses. `document_ai.status` bernilai `Approved`, `Declined`, atau `In Review`; setiap masalah yang terdeteksi dirinci dalam `document_ai.warnings`. Dokumen yang bermasalah tetap menghasilkan `200` — periksa isi respons, bukan hanya kode HTTP. Ketika `save_api_request=true`, `request_id` adalah ID sesi yang disimpan.",
            "content": {
              "application/json": {
                "examples": {
                  "Approved": {
                    "summary": "Slip gaji terbaca dengan jelas, nama cocok",
                    "value": {
                      "request_id": "9d6a3b1e-2f0c-4a8e-9b7d-1c2e3f4a5b6c",
                      "document_ai": {
                        "status": "Approved",
                        "extracted_data": {
                          "employer_name": "Acme Payments Ltd",
                          "employee_name": "Sophia Martinez",
                          "net_pay": 3120.5,
                          "pay_date": "2026-07-31"
                        },
                        "detected_codes": [
                          {
                            "type": "CODE_128",
                            "page_number": 1,
                            "position": [
                              [
                                96,
                                456
                              ],
                              [
                                96,
                                616
                              ],
                              [
                                1012,
                                611
                              ],
                              [
                                1015,
                                456
                              ]
                            ],
                            "x": 96,
                            "y": 456,
                            "width": 919,
                            "height": 160,
                            "page_width": 1200,
                            "page_height": 1700,
                            "raw_payload": "SU5WLTIwMjYtMDA0Mg==",
                            "parsed_payload": "INV-2026-0042"
                          }
                        ],
                        "fields": [
                          {
                            "key": "employer_name",
                            "name": "Employer name",
                            "instruction": "The employer or company issuing the payslip.",
                            "type": "text",
                            "required": true,
                            "is_full_name": false
                          },
                          {
                            "key": "employee_name",
                            "name": "Employee name",
                            "instruction": "The full name of the employee as printed on the payslip.",
                            "type": "text",
                            "required": true,
                            "is_full_name": true
                          },
                          {
                            "key": "net_pay",
                            "name": "Net pay",
                            "instruction": "The net amount paid to the employee for the period.",
                            "type": "number",
                            "required": true,
                            "is_full_name": false
                          },
                          {
                            "key": "pay_date",
                            "name": "Pay date",
                            "instruction": "The payment date shown on the payslip.",
                            "type": "date",
                            "required": false,
                            "is_full_name": false
                          }
                        ],
                        "name_match_score": 100.0,
                        "name_on_document": "Sophia Martinez",
                        "warnings": []
                      },
                      "vendor_data": "user-123",
                      "metadata": {
                        "flow": "onboarding"
                      },
                      "created_at": "2026-08-19T16:40:12.318Z"
                    }
                  },
                  "In Review — missing required field": {
                    "summary": "`net_pay` tidak dapat dibaca; tindakan default REVIEW",
                    "value": {
                      "request_id": "3f2a9c7b-5d4e-4b1a-8c6f-0e9d8c7b6a5f",
                      "document_ai": {
                        "status": "In Review",
                        "extracted_data": {
                          "employer_name": "Acme Payments Ltd",
                          "employee_name": "Sophia Martinez",
                          "net_pay": null,
                          "pay_date": "2026-07-31"
                        },
                        "detected_codes": [],
                        "fields": [
                          {
                            "key": "employer_name",
                            "name": "Employer name",
                            "instruction": "The employer or company issuing the payslip.",
                            "type": "text",
                            "required": true,
                            "is_full_name": false
                          },
                          {
                            "key": "employee_name",
                            "name": "Employee name",
                            "instruction": "The full name of the employee as printed on the payslip.",
                            "type": "text",
                            "required": true,
                            "is_full_name": true
                          },
                          {
                            "key": "net_pay",
                            "name": "Net pay",
                            "instruction": "The net amount paid to the employee for the period.",
                            "type": "number",
                            "required": true,
                            "is_full_name": false
                          },
                          {
                            "key": "pay_date",
                            "name": "Pay date",
                            "instruction": "The payment date shown on the payslip.",
                            "type": "date",
                            "required": false,
                            "is_full_name": false
                          }
                        ],
                        "name_match_score": 100.0,
                        "name_on_document": "Sophia Martinez",
                        "warnings": [
                          {
                            "risk": "DOCUMENT_AI_MISSING_REQUIRED_FIELDS",
                            "feature": "DOCUMENT_AI",
                            "additional_data": {
                              "missing_fields": [
                                "Net pay"
                              ]
                            },
                            "log_type": "warning",
                            "short_description": "Required fields could not be extracted",
                            "long_description": "One or more fields configured as required could not be extracted from the uploaded document."
                          }
                        ]
                      },
                      "vendor_data": null,
                      "metadata": null,
                      "created_at": "2026-08-19T16:41:05.002Z"
                    }
                  },
                  "Declined — suspected manipulation": {
                    "summary": "Forensik PDF menandai editor yang dikenal; tindakan default DECLINE",
                    "value": {
                      "request_id": "7c1d2e3f-4a5b-4c6d-8e9f-0a1b2c3d4e5f",
                      "document_ai": {
                        "status": "Declined",
                        "extracted_data": {
                          "employer_name": "Acme Payments Ltd",
                          "employee_name": "Sophia Martinez",
                          "net_pay": 3120.5,
                          "pay_date": "2026-07-31"
                        },
                        "detected_codes": [],
                        "fields": [
                          {
                            "key": "employer_name",
                            "name": "Employer name",
                            "instruction": "The employer or company issuing the payslip.",
                            "type": "text",
                            "required": true,
                            "is_full_name": false
                          },
                          {
                            "key": "employee_name",
                            "name": "Employee name",
                            "instruction": "The full name of the employee as printed on the payslip.",
                            "type": "text",
                            "required": true,
                            "is_full_name": true
                          },
                          {
                            "key": "net_pay",
                            "name": "Net pay",
                            "instruction": "The net amount paid to the employee for the period.",
                            "type": "number",
                            "required": true,
                            "is_full_name": false
                          },
                          {
                            "key": "pay_date",
                            "name": "Pay date",
                            "instruction": "The payment date shown on the payslip.",
                            "type": "date",
                            "required": false,
                            "is_full_name": false
                          }
                        ],
                        "name_match_score": null,
                        "name_on_document": "Sophia Martinez",
                        "warnings": [
                          {
                            "risk": "DOCUMENT_AI_SUSPECTED_MANIPULATION",
                            "feature": "DOCUMENT_AI",
                            "additional_data": {
                              "detection_method": "known_editor",
                              "processed_by_known_editor": "ilovepdf"
                            },
                            "log_type": "error",
                            "short_description": "Suspected document manipulation",
                            "long_description": "The system detected signs of potential manipulation or editing in the uploaded document."
                          }
                        ]
                      },
                      "vendor_data": null,
                      "metadata": null,
                      "created_at": "2026-08-19T16:42:40.771Z"
                    }
                  }
                },
                "schema": {
                  "type": "object",
                  "properties": {
                    "request_id": {
                      "type": "string",
                      "format": "uuid",
                      "description": "ID sesi yang disimpan saat `save_api_request=true` (dapat digunakan dengan `GET /v3/session/{sessionId}/decision/`); jika tidak, berupa UUID korelasi sementara."
                    },
                    "document_ai": {
                      "type": "object",
                      "properties": {
                        "status": {
                          "type": "string",
                          "enum": [
                            "Approved",
                            "Declined",
                            "In Review"
                          ],
                          "description": "`Approved` jika tidak ada peringatan yang menghasilkan penolakan atau peninjauan; `Declined` jika setidaknya satu risiko dipetakan ke `DECLINE`; selain itu `In Review` jika setidaknya satu dipetakan ke `REVIEW`. Daftar `warnings` menjelaskan alasannya."
                        },
                        "extracted_data": {
                          "type": "object",
                          "additionalProperties": true,
                          "description": "Satu entri per kunci kolom yang diminta. Nilai diberi tipe sesuai dengan `type` kolom — string untuk `text`, angka untuk `number`, string `YYYY-MM-DD` untuk `date` — atau `null` jika nilainya tidak dapat dibaca.",
                          "example": {
                            "employer_name": "Acme Payments Ltd",
                            "employee_name": "Sophia Martinez",
                            "net_pay": 3120.5,
                            "pay_date": "2026-07-31"
                          }
                        },
                        "detected_codes": {
                          "type": "array",
                          "description": "Kode QR dan barcode yang terdeteksi di setiap halaman yang diproses. Kosong jika tidak ada yang ditemukan. Kode QR yang ditemukan namun tidak dapat didekode memiliki `parsed_payload: null`.",
                          "items": {
                            "$ref": "#/components/schemas/DocumentAIDetectedCode"
                          }
                        },
                        "fields": {
                          "type": "array",
                          "description": "Definisi kolom yang dinormalisasi yang digunakan untuk ekstraksi ini, dikembalikan kembali (juga disimpan bersama sesi jika `save_api_request=true`).",
                          "items": {
                            "type": "object",
                            "properties": {
                              "key": {
                                "type": "string"
                              },
                              "name": {
                                "type": "string"
                              },
                              "instruction": {
                                "type": "string"
                              },
                              "type": {
                                "type": "string",
                                "enum": [
                                  "text",
                                  "number",
                                  "date"
                                ]
                              },
                              "required": {
                                "type": "boolean"
                              },
                              "is_full_name": {
                                "type": "boolean"
                              }
                            }
                          }
                        },
                        "name_match_score": {
                          "type": "number",
                          "nullable": true,
                          "minimum": 0,
                          "maximum": 100,
                          "description": "Kemiripan samar (0–100) antara `name_on_document` dan nama individu/perusahaan yang diharapkan. Dikembalikan setiap kali nilai nama dan nama yang diharapkan ada — pada kecocokan **dan** ketidakcocokan; selain itu bernilai `null`.",
                          "example": 96.0
                        },
                        "name_on_document": {
                          "type": "string",
                          "nullable": true,
                          "description": "Nilai nama yang diambil dari dokumen (kolom `is_full_name`, atau kolom teks pertama yang menyerupai nama) yang dibandingkan dengan nama yang diharapkan. `null` jika tidak ada nilai nama yang tersedia.",
                          "example": "Sophia Martinez"
                        },
                        "warnings": {
                          "type": "array",
                          "description": "Kosong jika persetujuan bersih. Setiap entri menjelaskan satu risiko yang terdeteksi; entri dengan `log_type: \"error\"` menetapkan `status` ke `Declined`, entri dengan `log_type: \"warning\"` menetapkannya ke `In Review`.",
                          "items": {
                            "type": "object",
                            "properties": {
                              "risk": {
                                "type": "string",
                                "enum": [
                                  "DOCUMENT_AI_UNREADABLE_DOCUMENT",
                                  "DOCUMENT_AI_MISSING_REQUIRED_FIELDS",
                                  "DOCUMENT_AI_SUSPECTED_MANIPULATION",
                                  "DOCUMENT_AI_NAME_MISMATCH",
                                  "DOCUMENT_AI_UNSUPPORTED_FILE"
                                ],
                                "description": "Kode risiko yang dapat dibaca mesin. Masing-masing diatur oleh opsi permintaan `document_ai_*_action` yang sesuai.",
                                "example": "DOCUMENT_AI_MISSING_REQUIRED_FIELDS"
                              },
                              "feature": {
                                "type": "string",
                                "enum": [
                                  "DOCUMENT_AI"
                                ],
                                "description": "Fitur yang memunculkan peringatan. Selalu `DOCUMENT_AI` pada endpoint ini."
                              },
                              "additional_data": {
                                "type": "object",
                                "nullable": true,
                                "additionalProperties": true,
                                "description": "Konteks tambahan untuk risiko: `{\"missing_fields\": [\"Net pay\"]}` untuk kolom wajib yang hilang, `{\"name_on_document\", \"score\", \"threshold\"}` untuk ketidakcocokan nama, dan temuan forensik (`detection_method`, detail produsen/editor) untuk dugaan manipulasi. `null` jika tidak ada yang perlu ditambahkan.",
                                "example": {
                                  "missing_fields": [
                                    "Net pay"
                                  ]
                                }
                              },
                              "log_type": {
                                "type": "string",
                                "enum": [
                                  "error",
                                  "warning",
                                  "information"
                                ],
                                "description": "Tingkat keparahan yang diturunkan dari tindakan yang dikonfigurasi: `error` (DECLINE), `warning` (REVIEW), `information` (NO_ACTION)."
                              },
                              "short_description": {
                                "type": "string",
                                "description": "Ringkasan singkat satu baris yang dapat dibaca manusia untuk risiko.",
                                "example": "Required fields could not be extracted"
                              },
                              "long_description": {
                                "type": "string",
                                "description": "Penjelasan yang mudah dibaca manusia, diinterpolasi dengan `additional_data` jika relevan."
                              }
                            }
                          }
                        }
                      }
                    },
                    "vendor_data": {
                      "type": "string",
                      "nullable": true,
                      "description": "Salinan `vendor_data` yang Anda kirimkan, atau `null`."
                    },
                    "metadata": {
                      "type": "object",
                      "nullable": true,
                      "additionalProperties": true,
                      "description": "Salinan objek `metadata` yang Anda kirimkan, atau `null`."
                    },
                    "created_at": {
                      "type": "string",
                      "format": "date-time",
                      "description": "Waktu permintaan diproses (UTC, ISO 8601)."
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Kesalahan validasi atau pemrosesan. Masalah tingkat kolom mengembalikan envelope standar DRF (satu array pesan per kolom yang bermasalah). Dokumen terenkripsi atau tidak terbaca serta kegagalan ekstraksi mengembalikan `{\"error\": ...}`.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing document": {
                    "summary": "`document` tidak disertakan dalam data formulir",
                    "value": {
                      "document": [
                        "No file was submitted."
                      ]
                    }
                  },
                  "Invalid fields payload": {
                    "summary": "`fields` bukan satu string array yang dikodekan sebagai JSON",
                    "value": {
                      "fields": [
                        "fields must be a valid JSON array string."
                      ]
                    }
                  },
                  "Duplicate field keys": {
                    "summary": "Dua item memiliki `key` yang sama",
                    "value": {
                      "fields": [
                        "Every fields item must have a unique key."
                      ]
                    }
                  },
                  "Conflicting expectations": {
                    "summary": "Ekspektasi individu dan perusahaan dikirim bersama",
                    "value": {
                      "non_field_errors": [
                        "Provide either person expected-name fields or expected_company_name, not both."
                      ]
                    }
                  },
                  "Invalid metadata": {
                    "summary": "`metadata` bukan objek JSON (atau berisi karakter NUL)",
                    "value": {
                      "metadata": [
                        "Metadata must be a JSON object."
                      ]
                    }
                  },
                  "Oversized vendor_data": {
                    "summary": "`vendor_data` melebihi batas 2.000 byte",
                    "value": {
                      "vendor_data": [
                        "vendor_data is too long (maximum 2000 bytes)."
                      ]
                    }
                  },
                  "Encrypted PDF": {
                    "summary": "PDF yang dilindungi kata sandi",
                    "value": {
                      "error": "The PDF is encrypted. Please upload a decrypted PDF or a photo instead."
                    }
                  },
                  "Extraction failed": {
                    "summary": "Pipeline ekstraksi tidak dapat memproses dokumen",
                    "value": {
                      "error": [
                        "Error extracting Document AI information"
                      ]
                    }
                  }
                },
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                }
              }
            }
          },
          "403": {
            "description": "Izin ditolak. Dikembalikan ketika header `x-api-key` tidak ada, dan juga ketika saldo organisasi pemanggil tidak dapat mencukupi biaya panggilan tersebut; kunci yang salah, dicabut, atau kedaluwarsa mengembalikan `401`. Kunci yang tidak ada mengembalikan `403` dengan `{\"detail\": ...}`; kunci yang salah, dicabut, atau kedaluwarsa mengembalikan `401`. Kekurangan kredit — serta organisasi dengan penagihan kontrak yang daftar tarifnya tidak memiliki entri API Document AI — mengembalikan `403` dengan `{\"error\": ...}` sebelum pemrosesan dokumen apa pun terjadi.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing or invalid API key": {
                    "summary": "Tidak ada header `x-api-key`, atau kuncinya tidak valid/dicabut",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Not enough credits": {
                    "summary": "Saldo organisasi tidak mencukupi untuk panggilan ini",
                    "value": {
                      "error": "You don't have enough credits to perform this request. Please top up at https://business.didit.me"
                    }
                  },
                  "Contract rate missing": {
                    "summary": "Organisasi yang ditagih berdasarkan kontrak yang daftar tarifnya tidak memiliki entri Document AI API",
                    "value": {
                      "error": "Document AI API is not included in your contract rate card. Contact support@didit.me to enable it."
                    }
                  }
                },
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    },
                    "error": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Batas laju terlampaui. Endpoint POST/PATCH/DELETE berbagi anggaran 300 permintaan penulisan per menit per kunci API (pembuatan transaksi dan ingesti event memiliki anggaran terpisah sebesar 600). Respons menyertakan header `X-RateLimit-Limit`, `X-RateLimit-Remaining`, `X-RateLimit-Reset`, dan `Retry-After`.",
            "content": {
              "application/json": {
                "examples": {
                  "Write rate limit exceeded": {
                    "summary": "Lebih dari 300 permintaan tulis pada menit ini",
                    "value": {
                      "detail": "Write request rate limit exceeded. You can make up to 300 requests per minute."
                    }
                  }
                },
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "503": {
            "$ref": "#/components/responses/DocumentProcessingBusy"
          }
        },
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.document_ai.analyze(\n    document=open(\"document.pdf\", \"rb\"),\n    fields=\"[{\\\"key\\\": \\\"employer_name\\\", \\\"name\\\": \\\"Employer name\\\", \\\"instruction\\\": \\\"The employer or company issuing the payslip.\\\", \\\"type\\\": \\\"text\\\", \\\"required\\\": true, \\\"is_full_name\\\": false}, {\\\"key\\\": \\\"employee_name\\\", \\\"name\\\": \\\"Employee name\\\", \\\"instruction\\\": \\\"The full name of the employee as printed on the payslip.\\\", \\\"type\\\": \\\"text\\\", \\\"required\\\": true, \\\"is_full_name\\\": true}, {\\\"key\\\": \\\"net_pay\\\", \\\"name\\\": \\\"Net pay\\\", \\\"instruction\\\": \\\"The net amount paid to the employee for the period.\\\", \\\"type\\\": \\\"number\\\", \\\"required\\\": true, \\\"is_full_name\\\": false}, {\\\"key\\\": \\\"pay_date\\\", \\\"name\\\": \\\"Pay date\\\", \\\"instruction\\\": \\\"The payment date shown on the payslip.\\\", \\\"type\\\": \\\"date\\\", \\\"required\\\": false, \\\"is_full_name\\\": false}]\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit, { fileFromPath } from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.documentAi.analyze({\n  document: await fileFromPath(\"document.pdf\"),\n  fields: \"[{\\\"key\\\": \\\"employer_name\\\", \\\"name\\\": \\\"Employer name\\\", \\\"instruction\\\": \\\"The employer or company issuing the payslip.\\\", \\\"type\\\": \\\"text\\\", \\\"required\\\": true, \\\"is_full_name\\\": false}, {\\\"key\\\": \\\"employee_name\\\", \\\"name\\\": \\\"Employee name\\\", \\\"instruction\\\": \\\"The full name of the employee as printed on the payslip.\\\", \\\"type\\\": \\\"text\\\", \\\"required\\\": true, \\\"is_full_name\\\": true}, {\\\"key\\\": \\\"net_pay\\\", \\\"name\\\": \\\"Net pay\\\", \\\"instruction\\\": \\\"The net amount paid to the employee for the period.\\\", \\\"type\\\": \\\"number\\\", \\\"required\\\": true, \\\"is_full_name\\\": false}, {\\\"key\\\": \\\"pay_date\\\", \\\"name\\\": \\\"Pay date\\\", \\\"instruction\\\": \\\"The payment date shown on the payslip.\\\", \\\"type\\\": \\\"date\\\", \\\"required\\\": false, \\\"is_full_name\\\": false}]\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.DocumentAi.Analyze(ctx, didit.DocumentAiAnalyzeParams{\n\tDocument: didit.FileFromPath(\"document.pdf\"),\n\tFields:   \"[{\\\"key\\\": \\\"employer_name\\\", \\\"name\\\": \\\"Employer name\\\", \\\"instruction\\\": \\\"The employer or company issuing the payslip.\\\", \\\"type\\\": \\\"text\\\", \\\"required\\\": true, \\\"is_full_name\\\": false}, {\\\"key\\\": \\\"employee_name\\\", \\\"name\\\": \\\"Employee name\\\", \\\"instruction\\\": \\\"The full name of the employee as printed on the payslip.\\\", \\\"type\\\": \\\"text\\\", \\\"required\\\": true, \\\"is_full_name\\\": true}, {\\\"key\\\": \\\"net_pay\\\", \\\"name\\\": \\\"Net pay\\\", \\\"instruction\\\": \\\"The net amount paid to the employee for the period.\\\", \\\"type\\\": \\\"number\\\", \\\"required\\\": true, \\\"is_full_name\\\": false}, {\\\"key\\\": \\\"pay_date\\\", \\\"name\\\": \\\"Pay date\\\", \\\"instruction\\\": \\\"The payment date shown on the payslip.\\\", \\\"type\\\": \\\"date\\\", \\\"required\\\": false, \\\"is_full_name\\\": false}]\",\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.nio.file.Path;\nimport me.didit.Didit;\nimport me.didit.types.DocumentAiAnalyzeParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.documentAi().analyze(DocumentAiAnalyzeParams.builder()\n        .document(Path.of(\"document.pdf\"))\n        .fields(\"[{\\\"key\\\": \\\"employer_name\\\", \\\"name\\\": \\\"Employer name\\\", \\\"instruction\\\": \\\"The employer or company issuing the payslip.\\\", \\\"type\\\": \\\"text\\\", \\\"required\\\": true, \\\"is_full_name\\\": false}, {\\\"key\\\": \\\"employee_name\\\", \\\"name\\\": \\\"Employee name\\\", \\\"instruction\\\": \\\"The full name of the employee as printed on the payslip.\\\", \\\"type\\\": \\\"text\\\", \\\"required\\\": true, \\\"is_full_name\\\": true}, {\\\"key\\\": \\\"net_pay\\\", \\\"name\\\": \\\"Net pay\\\", \\\"instruction\\\": \\\"The net amount paid to the employee for the period.\\\", \\\"type\\\": \\\"number\\\", \\\"required\\\": true, \\\"is_full_name\\\": false}, {\\\"key\\\": \\\"pay_date\\\", \\\"name\\\": \\\"Pay date\\\", \\\"instruction\\\": \\\"The payment date shown on the payslip.\\\", \\\"type\\\": \\\"date\\\", \\\"required\\\": false, \\\"is_full_name\\\": false}]\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\nuse Didit\\File;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->documentAi->analyze([\n    'document' => File::fromPath('document.pdf'),\n    'fields' => '[{\"key\": \"employer_name\", \"name\": \"Employer name\", \"instruction\": \"The employer or company issuing the payslip.\", \"type\": \"text\", \"required\": true, \"is_full_name\": false}, {\"key\": \"employee_name\", \"name\": \"Employee name\", \"instruction\": \"The full name of the employee as printed on the payslip.\", \"type\": \"text\", \"required\": true, \"is_full_name\": true}, {\"key\": \"net_pay\", \"name\": \"Net pay\", \"instruction\": \"The net amount paid to the employee for the period.\", \"type\": \"number\", \"required\": true, \"is_full_name\": false}, {\"key\": \"pay_date\", \"name\": \"Pay date\", \"instruction\": \"The payment date shown on the payslip.\", \"type\": \"date\", \"required\": false, \"is_full_name\": false}]',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.document_ai.analyze(\n  document: Pathname(\"document.pdf\"),\n  fields: \"[{\\\"key\\\": \\\"employer_name\\\", \\\"name\\\": \\\"Employer name\\\", \\\"instruction\\\": \\\"The employer or company issuing the payslip.\\\", \\\"type\\\": \\\"text\\\", \\\"required\\\": true, \\\"is_full_name\\\": false}, {\\\"key\\\": \\\"employee_name\\\", \\\"name\\\": \\\"Employee name\\\", \\\"instruction\\\": \\\"The full name of the employee as printed on the payslip.\\\", \\\"type\\\": \\\"text\\\", \\\"required\\\": true, \\\"is_full_name\\\": true}, {\\\"key\\\": \\\"net_pay\\\", \\\"name\\\": \\\"Net pay\\\", \\\"instruction\\\": \\\"The net amount paid to the employee for the period.\\\", \\\"type\\\": \\\"number\\\", \\\"required\\\": true, \\\"is_full_name\\\": false}, {\\\"key\\\": \\\"pay_date\\\", \\\"name\\\": \\\"Pay date\\\", \\\"instruction\\\": \\\"The payment date shown on the payslip.\\\", \\\"type\\\": \\\"date\\\", \\\"required\\\": false, \\\"is_full_name\\\": false}]\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.DocumentAi.AnalyzeAsync(new DocumentAiAnalyzeParams\n{\n    Document = FileUpload.FromPath(\"document.pdf\"),\n    Fields = \"[{\\\"key\\\": \\\"employer_name\\\", \\\"name\\\": \\\"Employer name\\\", \\\"instruction\\\": \\\"The employer or company issuing the payslip.\\\", \\\"type\\\": \\\"text\\\", \\\"required\\\": true, \\\"is_full_name\\\": false}, {\\\"key\\\": \\\"employee_name\\\", \\\"name\\\": \\\"Employee name\\\", \\\"instruction\\\": \\\"The full name of the employee as printed on the payslip.\\\", \\\"type\\\": \\\"text\\\", \\\"required\\\": true, \\\"is_full_name\\\": true}, {\\\"key\\\": \\\"net_pay\\\", \\\"name\\\": \\\"Net pay\\\", \\\"instruction\\\": \\\"The net amount paid to the employee for the period.\\\", \\\"type\\\": \\\"number\\\", \\\"required\\\": true, \\\"is_full_name\\\": false}, {\\\"key\\\": \\\"pay_date\\\", \\\"name\\\": \\\"Pay date\\\", \\\"instruction\\\": \\\"The payment date shown on the payslip.\\\", \\\"type\\\": \\\"date\\\", \\\"required\\\": false, \\\"is_full_name\\\": false}]\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/aml/": {
      "post": {
        "summary": "Skrining AML (mandiri)",
        "operationId": "post_v3aml",
        "x-didit-sdk": {
          "resource": "aml",
          "method": "screen",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Standalone APIs"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "Kunci keamanan percobaan ulang opsional, hingga 255 karakter. Menggunakan kembali kunci yang sama dengan body permintaan yang sama akan mengembalikan respons asli tanpa menjalankan atau menagih biaya untuk skrining kedua. Menggunakan kembali kunci dengan body yang berbeda akan mengembalikan `409`.",
            "schema": {
              "type": "string",
              "maxLength": 255
            }
          }
        ],
        "description": "Lakukan skrining individu atau perusahaan terhadap dataset PEP, sanksi, peringatan/daftar pantauan, dan media negatif dalam satu panggilan.\n\n**Model dua skor.** Setiap temuan memiliki `match_score` (0–100, keyakinan identitas) dan `risk_score` (0–100, risiko entitas). Temuan yang memiliki `match_score` di bawah `aml_match_score_threshold` (default **93**) diberi tag `review_status: \"False Positive\"` dan diabaikan untuk tujuan risiko; `risk_score` tertinggi di antara temuan yang tersisa menjadi `aml.score`. `aml.status` akhir mengikuti ambang batas Anda: `score` > `aml_score_review_threshold` (default **100**) → `Declined`; `score` > `aml_score_approve_threshold` (default **80**) → `In Review`; jika tidak, `Approved`. Kapan pun `score` bernilai bukan nol dan ≥ ambang batas persetujuan, peringatan `POSSIBLE_MATCH_FOUND` ditambahkan (skor tepat 0 tidak pernah memunculkan peringatan).\n\n**Bobot skor kecocokan.** `aml_name_weight` + `aml_dob_weight` + `aml_country_weight` harus berjumlah tepat 100 (default 60/25/15). Komponen yang tidak ada dalam permintaan dinormalisasi ulang; `document_number` yang cocok berfungsi sebagai kunci utama yang menggantikan `match_score` menjadi 100.\n\n**Latensi.** Skrining biasa umumnya selesai dalam beberapa detik. Dengan `include_adverse_media=true`, API menunggu pengayaan media negatif (jeda awal ~5 detik ditambah polling hingga ~25 detik) — konfigurasikan batas waktu klien **setidaknya 60 detik**.\n\n**Persistensi.** `save_api_request` default-nya adalah **true**: skrining disimpan sebagai sesi (`request_id` berfungsi dengan `GET /v3/session/{sessionId}/decision/`), muncul di konsol, webhook `status.updated` terpicu, dan status peninjauan temuan dapat diperbarui nanti. Dengan `save_api_request=false`, tidak ada yang disimpan dan `request_id` adalah ID korelasi sementara. `include_ongoing_monitoring=true` terus melakukan skrining ulang profil dan memerlukan `save_api_request=true` (ditegakkan dengan `400`).\n\n**Idempotensi.** Kirim header `Idempotency-Key` saat mencoba lagi setelah batas waktu atau kesalahan sementara. Kunci ini berlaku untuk aplikasi Anda dan isi permintaan yang persis sama. Permintaan pertama yang selesai menyimpan responsnya; percobaan ulang berikutnya yang identik mengembalikan respons yang sama dan tidak menjalankan atau menagih skrining AML lainnya. Jika permintaan awal masih berjalan, coba lagi nanti dengan kunci yang sama. Jika kunci yang sama digunakan kembali dengan body yang berbeda, API mengembalikan `409`.\n\n**Penagihan.** Satu kredit AML API dikenakan setelah skrining pertama yang berhasil. Respons idempoten yang diputar ulang tidak dikenakan biaya lagi; saldo yang tidak mencukupi mengembalikan `403` sebelum skrining baru dilakukan.\n\n**Sandbox.** Kunci dari aplikasi sandbox melewati skrining dan penagihan sepenuhnya dan mengembalikan hasil tiruan — `Approved` dengan nol temuan kecuali Anda meneruskan `sandbox_scenario`. `save_api_request` berfungsi sama seperti pada kunci produksi, sehingga skrining sandbox yang disimpan dapat diambil melalui `GET /v3/session/{sessionId}/decision/` dan `GET /v3/session/{sessionId}/generate-pdf/`.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "full_name"
                ],
                "properties": {
                  "full_name": {
                    "type": "string",
                    "minLength": 2,
                    "description": "Nama lengkap individu atau perusahaan yang akan diskrining. Minimum **2 karakter** - batas minimum dari penyedia skrining itu sendiri. Nama yang lebih pendek atau kosong akan mengembalikan `400` pada kolom ini sebelum skrining apa pun dijalankan, sehingga tidak ada yang ditagihkan.",
                    "example": "Antonio Ejemplo Modelo"
                  },
                  "entity_type": {
                    "type": "string",
                    "enum": [
                      "person",
                      "company"
                    ],
                    "default": "person",
                    "description": "Jenis entitas yang akan diskrining. Secara default adalah `person`."
                  },
                  "date_of_birth": {
                    "type": "string",
                    "format": "date",
                    "description": "Tanggal lahir (perorangan) atau tanggal pendirian (perusahaan), `YYYY-MM-DD`. Meningkatkan presisi kecocokan melalui bobot DOB.",
                    "example": "1972-02-29"
                  },
                  "nationality": {
                    "type": "string",
                    "description": "Kode negara ISO 3166-1 **alpha-2** (misalnya `ES`). Kode tidak valid mengembalikan `400`. Meningkatkan presisi pencocokan melalui bobot negara.",
                    "example": "ES"
                  },
                  "document_number": {
                    "type": "string",
                    "description": "Nomor dokumen identitas. Tidak diberi bobot — bertindak sebagai kunci emas: kecocokan persis akan menimpa `match_score` hasil pencarian menjadi 100, sedangkan ketidakcocokan total akan memotong skornya. Dikirim ke penyedia skrining sebagai filter pencarian hanya jika berukuran **2-50 karakter**; nilai di luar rentang tersebut diterima dan disimpan, dan skrining tetap berjalan serta ditagih, hanya saja tidak dipersempit berdasarkan nomor dokumen."
                  },
                  "aml_score_approve_threshold": {
                    "type": "number",
                    "minimum": 0,
                    "maximum": 100,
                    "default": 80,
                    "description": "Ambang batas skor risiko yang pada atau di bawahnya menghasilkan `Approved`. Harus ≤ `aml_score_review_threshold` (jika tidak, `400`)."
                  },
                  "aml_score_review_threshold": {
                    "type": "number",
                    "minimum": 0,
                    "maximum": 100,
                    "default": 100,
                    "description": "Ambang batas skor risiko yang jika dilampaui menghasilkan `Declined`. Skor di antara kedua ambang batas menghasilkan `In Review`."
                  },
                  "aml_name_weight": {
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 100,
                    "default": 60,
                    "description": "Bobot kemiripan nama dalam skor kecocokan per entri yang cocok. Ketiga bobot harus berjumlah tepat 100 (jika tidak, `400`)."
                  },
                  "aml_dob_weight": {
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 100,
                    "default": 25,
                    "description": "Bobot tanggal lahir dalam skor kecocokan per entri yang cocok."
                  },
                  "aml_country_weight": {
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 100,
                    "default": 15,
                    "description": "Bobot negara/kewarganegaraan dalam skor kecocokan per entri yang cocok."
                  },
                  "aml_match_score_threshold": {
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 100,
                    "default": 93,
                    "description": "Batas per hit: hit dengan `match_score` di bawah nilai ini dianggap `False Positive` (dikecualikan dari penilaian risiko); nilai yang sama atau di atasnya dianggap kecocokan potensial `Unreviewed`."
                  },
                  "include_adverse_media": {
                    "type": "boolean",
                    "default": false,
                    "description": "Cari juga media berita untuk liputan negatif. Menambah latensi hingga ~30 dtk saat hasil dikumpulkan — gunakan batas waktu klien ≥60 dtk."
                  },
                  "include_ongoing_monitoring": {
                    "type": "boolean",
                    "default": false,
                    "description": "Tetap lakukan skrining ulang profil ini dan kirimkan perubahan melalui webhook. Memerlukan `save_api_request=true` (jika tidak, `400`)."
                  },
                  "save_api_request": {
                    "type": "boolean",
                    "default": true,
                    "description": "Simpan skrining sebagai sesi (visibilitas konsol, endpoint keputusan, webhook, peninjauan hit). Atur ke `false` untuk pemeriksaan tanpa status."
                  },
                  "vendor_data": {
                    "type": "string",
                    "description": "Pengenal Anda untuk pengguna yang diskrining; dikembalikan dan disimpan bersama sesi."
                  },
                  "metadata": {
                    "type": "object",
                    "nullable": true,
                    "description": "JSON bentuk bebas yang disimpan bersama permintaan dan dikembalikan dalam respons."
                  },
                  "sandbox_scenario": {
                    "type": "string",
                    "description": "Slug skenario khusus sandbox. Hanya diterima jika kunci API milik aplikasi mode sandbox; ditolak pada aplikasi di lingkungan produksi. Skrining mandiri tidak memiliki sesi untuk dipicu, jadi slug diletakkan langsung pada permintaan skrining: `decline_aml_hit` mengembalikan satu kecocokan berformat produksi dan menetapkan skrining sebagai `Declined`, `review_aml_possible_match` menetapkannya sebagai `In Review`, dan skenario yang tidak menetapkan hasil AML akan membiarkan skrining bersih. Lihat katalog skenario di GET /v1/sandbox/scenarios/ atau [Sandbox & Test Data](/id/integration/sandbox-testing).",
                    "example": "decline_aml_hit"
                  }
                }
              },
              "example": {
                "full_name": "Antonio Ejemplo Modelo",
                "entity_type": "person",
                "date_of_birth": "1972-02-29",
                "nationality": "ES",
                "include_adverse_media": false,
                "vendor_data": "user-1234"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST https://verification.didit.me/v3/aml/ \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -H 'Idempotency-Key: aml-user-1234-2026-08-20' \\\n  -d '{\n    \"full_name\": \"Antonio Ejemplo Modelo\",\n    \"entity_type\": \"person\",\n    \"date_of_birth\": \"1972-02-29\",\n    \"nationality\": \"ES\",\n    \"include_adverse_media\": false,\n    \"vendor_data\": \"user-1234\"\n  }'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.aml.screen(\n    full_name=\"Antonio Ejemplo Modelo\",\n    entity_type=\"person\",\n    date_of_birth=\"1972-02-29\",\n    nationality=\"ES\",\n    include_adverse_media=False,\n    vendor_data=\"user-1234\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.aml.screen({\n  full_name: \"Antonio Ejemplo Modelo\",\n  entity_type: \"person\",\n  date_of_birth: \"1972-02-29\",\n  nationality: \"ES\",\n  include_adverse_media: false,\n  vendor_data: \"user-1234\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.AML.Screen(ctx, didit.AMLScreenParams{\n\tFullName:            \"Antonio Ejemplo Modelo\",\n\tEntityType:          didit.Some(didit.AMLScreenParamsEntityType(\"person\")),\n\tDateOfBirth:         didit.String(\"1972-02-29\"),\n\tNationality:         didit.String(\"ES\"),\n\tIncludeAdverseMedia: didit.Bool(false),\n\tVendorData:          didit.String(\"user-1234\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.time.LocalDate;\nimport me.didit.Didit;\nimport me.didit.types.AmlScreenParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.aml().screen(AmlScreenParams.builder()\n        .fullName(\"Antonio Ejemplo Modelo\")\n        .entityType(AmlScreenParams.EntityType.of(\"person\"))\n        .dateOfBirth(LocalDate.parse(\"1972-02-29\"))\n        .nationality(\"ES\")\n        .includeAdverseMedia(false)\n        .vendorData(\"user-1234\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->aml->screen([\n    'full_name' => 'Antonio Ejemplo Modelo',\n    'entity_type' => 'person',\n    'date_of_birth' => '1972-02-29',\n    'nationality' => 'ES',\n    'include_adverse_media' => false,\n    'vendor_data' => 'user-1234',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.aml.screen(\n  full_name: \"Antonio Ejemplo Modelo\",\n  entity_type: \"person\",\n  date_of_birth: \"1972-02-29\",\n  nationality: \"ES\",\n  include_adverse_media: false,\n  vendor_data: \"user-1234\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Aml.ScreenAsync(new AmlScreenParams\n{\n    FullName = \"Antonio Ejemplo Modelo\",\n    EntityType = new AmlScreenParamsEntityType(\"person\"),\n    DateOfBirth = \"1972-02-29\",\n    Nationality = \"ES\",\n    IncludeAdverseMedia = false,\n    VendorData = \"user-1234\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "Skrining selesai. `aml.status` mencerminkan ambang batas Anda; setiap temuan pada atau di atas batas minimum inklusi internal tercantum dalam `aml.hits` dengan `match_score` untuk identitas, `risk_score` untuk entitas, dan `score_breakdown` yang menjelaskan kecocokan tersebut.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "request_id": {
                      "type": "string",
                      "format": "uuid",
                      "description": "ID sesi yang disimpan saat `save_api_request=true` (dapat digunakan dengan `GET /v3/session/{sessionId}/decision/`); jika tidak, berupa UUID korelasi sementara."
                    },
                    "aml": {
                      "type": "object",
                      "properties": {
                        "status": {
                          "type": "string",
                          "enum": [
                            "Approved",
                            "In Review",
                            "Declined"
                          ],
                          "description": "`Declined` ketika `score` > `aml_score_review_threshold`; `In Review` ketika `score` > `aml_score_approve_threshold`; `Approved` jika tidak (termasuk ketika tidak ada skor yang tersedia)."
                        },
                        "total_hits": {
                          "type": "integer",
                          "description": "Jumlah entri dalam `hits`."
                        },
                        "entity_type": {
                          "type": "string",
                          "enum": [
                            "person",
                            "company"
                          ],
                          "description": "Menampilkan kembali jenis entitas yang diskrining."
                        },
                        "hits": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "description": "Satu hit skrining. `match_score` (0–100) mengukur keyakinan identitas — hit di bawah `aml_match_score_threshold` diberi tag `review_status: \"False Positive\"` dan dikecualikan dari penilaian risiko; hit pada atau di atasnya adalah kecocokan potensial `\"Unreviewed\"`. `risk_score` (0–100) mengukur seberapa berisiko entitas yang cocok dan menentukan `aml.score` tingkat atas.",
                            "properties": {
                              "id": {
                                "type": "string",
                                "nullable": true,
                                "description": "Pengenal stabil dari Didit untuk hit: `hit_` yang diikuti oleh 24 karakter heksadesimal. Entitas cocok yang sama mempertahankan `id` yang sama saat subjek menjalani skrining ulang. Teruskan ini sebagai `hit_id` ke endpoint peninjauan hit AML."
                              },
                              "url": {
                                "type": "string",
                                "nullable": true,
                                "description": "URL sumber untuk entitas yang cocok, jika tersedia."
                              },
                              "match": {
                                "type": "boolean",
                                "nullable": true,
                                "description": "Flag pencocokan persis lama. Sebaiknya gunakan `match_score` + `review_status`."
                              },
                              "score": {
                                "type": "number",
                                "nullable": true,
                                "description": "USANG skor kecocokan berbobot dalam rentang 0–1. Gunakan `match_score` sebagai gantinya."
                              },
                              "match_score": {
                                "type": "number",
                                "nullable": true,
                                "description": "Keyakinan identitas (0–100). Dibandingkan dengan `aml_match_score_threshold` untuk memisahkan Positif Palsu dari Kemungkinan Kecocokan."
                              },
                              "risk_score": {
                                "type": "number",
                                "nullable": true,
                                "description": "Skor risiko entitas (0–100). `risk_score` tertinggi di antara kecocokan yang bukan positif palsu menjadi `aml.score` tingkat atas."
                              },
                              "target": {
                                "type": "boolean",
                                "nullable": true
                              },
                              "caption": {
                                "type": "string",
                                "nullable": true,
                                "description": "Nama tampilan entitas yang cocok."
                              },
                              "datasets": {
                                "type": "array",
                                "nullable": true,
                                "items": {
                                  "type": "string",
                                  "enum": [
                                    "PEP",
                                    "PEP Level 1",
                                    "PEP Level 2",
                                    "PEP Level 3",
                                    "PEP Level 4",
                                    "Sanctions",
                                    "Adverse Media",
                                    "Warnings and Regulatory Enforcement",
                                    "Fitness and Probity",
                                    "SIP",
                                    "SIE",
                                    "Insolvency",
                                    "Other Lists"
                                  ]
                                },
                                "description": "Kategori risiko tempat entitas terdaftar: `PEP` (dengan tingkatannya, `PEP Level 1` hingga `PEP Level 4`), `Sanctions`, `Adverse Media`, `Warnings and Regulatory Enforcement`, `Fitness and Probity`, `SIP`, `SIE`, atau `Insolvency`. `Other Lists` saat sumber entitas tidak menyatakan kategori-kategori ini."
                              },
                              "features": {
                                "type": "object",
                                "nullable": true
                              },
                              "properties": {
                                "type": "object",
                                "nullable": true,
                                "description": "Profil entitas: `name`, `alias`, `notes`, `gender`, `birthDate`, `birthPlace`, `nationality`, `position`, dan larik biografis lainnya (masing-masing nullable)."
                              },
                              "rca_name": {
                                "type": "string",
                                "nullable": true,
                                "description": "Nama rekan dekat terkait yang menjadi perantara pencocokan entitas, ketika temuan berupa RCA."
                              },
                              "pep_matches": {
                                "type": "array",
                                "description": "Entri daftar PEP yang mendukung kecocokan ini.",
                                "items": {
                                  "type": "object",
                                  "properties": {
                                    "list_name": {
                                      "type": "string"
                                    },
                                    "publisher": {
                                      "type": "string"
                                    },
                                    "source_url": {
                                      "type": "string"
                                    },
                                    "description": {
                                      "type": "string"
                                    },
                                    "matched_name": {
                                      "type": "string"
                                    },
                                    "pep_position": {
                                      "type": "string"
                                    },
                                    "date_of_birth": {
                                      "type": "string"
                                    },
                                    "place_of_birth": {
                                      "type": "string"
                                    },
                                    "aliases": {
                                      "type": "array",
                                      "items": {
                                        "type": "string"
                                      }
                                    },
                                    "education": {
                                      "type": "array",
                                      "items": {
                                        "type": "string"
                                      }
                                    },
                                    "other_sources": {
                                      "type": "array",
                                      "items": {
                                        "type": "string"
                                      }
                                    }
                                  }
                                }
                              },
                              "sanction_matches": {
                                "type": "array",
                                "items": {
                                  "type": "object"
                                },
                                "description": "Entri daftar sanksi yang mendasari kecocokan ini (struktur daftar pendukung yang sama dengan `pep_matches`, ditambah kolom khusus sanksi)."
                              },
                              "warning_matches": {
                                "type": "array",
                                "items": {
                                  "type": "object"
                                },
                                "description": "Entri peringatan/daftar pantauan yang mendasari kecocokan ini."
                              },
                              "adverse_media_matches": {
                                "type": "array",
                                "description": "Artikel media negatif. Terisi hanya jika `include_adverse_media=true`.",
                                "items": {
                                  "type": "object",
                                  "properties": {
                                    "headline": {
                                      "type": "string"
                                    },
                                    "summary": {
                                      "type": "string"
                                    },
                                    "sentiment": {
                                      "type": "string"
                                    },
                                    "sentiment_score": {
                                      "type": "number"
                                    },
                                    "source_url": {
                                      "type": "string"
                                    },
                                    "thumbnail": {
                                      "type": "string",
                                      "nullable": true
                                    },
                                    "country": {
                                      "type": "string",
                                      "nullable": true
                                    },
                                    "author_name": {
                                      "type": "string",
                                      "nullable": true
                                    },
                                    "publication_date": {
                                      "type": "string",
                                      "nullable": true
                                    },
                                    "adverse_keywords": {
                                      "type": "array",
                                      "items": {
                                        "type": "string"
                                      }
                                    },
                                    "other_sources": {
                                      "type": "array",
                                      "items": {
                                        "type": "string"
                                      }
                                    }
                                  }
                                }
                              },
                              "adverse_media_details": {
                                "type": "object",
                                "nullable": true,
                                "description": "Sentimen media negatif agregat untuk entitas (`sentiment`, `sentiment_score`, peta frekuensi `adverse_keywords`). Terisi hanya jika `include_adverse_media=true`."
                              },
                              "first_seen": {
                                "type": "string",
                                "format": "date-time",
                                "nullable": true,
                                "description": "Waktu ketika entitas pertama kali muncul dalam kumpulan data."
                              },
                              "last_seen": {
                                "type": "string",
                                "format": "date-time",
                                "nullable": true,
                                "description": "Pembaruan himpunan data terbaru yang menyertakan entitas tersebut."
                              },
                              "linked_entities": {
                                "type": "array",
                                "description": "Hubungan yang diketahui dari entitas yang cocok (keluarga, rekanan, perusahaan).",
                                "items": {
                                  "type": "object",
                                  "properties": {
                                    "name": {
                                      "type": "array",
                                      "items": {
                                        "type": "string"
                                      }
                                    },
                                    "relation": {
                                      "type": "array",
                                      "items": {
                                        "type": "string"
                                      }
                                    },
                                    "status": {
                                      "type": "array",
                                      "items": {
                                        "type": "string"
                                      }
                                    },
                                    "details": {
                                      "type": "array",
                                      "items": {
                                        "type": "string"
                                      }
                                    },
                                    "active": {
                                      "type": "array",
                                      "items": {
                                        "type": "string"
                                      }
                                    }
                                  }
                                }
                              },
                              "risk_view": {
                                "type": "object",
                                "nullable": true,
                                "description": "Rincian risiko per dimensi (`crimes`, `countries`, `categories`, `custom_list`), masing-masing dengan `score`, `weightage`, `risk_level`, dan peta `risk_scores`."
                              },
                              "additional_information": {
                                "type": "object",
                                "nullable": true,
                                "description": "Konteks tambahan bentuk bebas, misalnya array `flag_summary` yang menjelaskan mengapa entitas ditandai."
                              },
                              "review_status": {
                                "type": "string",
                                "nullable": true,
                                "enum": [
                                  "False Positive",
                                  "Unreviewed",
                                  "Confirmed Match",
                                  "Inconclusive"
                                ],
                                "description": "`False Positive` — `match_score` di bawah `aml_match_score_threshold`, dikecualikan dari penilaian risiko. `Unreviewed` — kemungkinan kecocokan yang menunggu peninjauan. `Confirmed Match` / `Inconclusive` — diatur secara manual oleh peninjau (melalui Business Console) pada sesi yang disimpan; kemampuan peninjauan tersebut bukan merupakan bagian dari spesifikasi ini."
                              },
                              "score_breakdown": {
                                "type": "object",
                                "nullable": true,
                                "description": "Cara `match_score` dihitung. Nama, tanggal lahir, dan negara masing-masing menyumbang `<component>_score` × `<component>_weight_normalized` poin; bobot dinormalisasi ulang saat suatu komponen tidak ada dalam data yang diskrining. Nomor dokumen tidak dibobotkan - nomor tersebut bertindak sebagai 'golden key': `MATCH` mengganti skor menjadi 100, `NEUTRAL` membiarkannya tidak berubah, `HARD_MISMATCH` menerapkan penalti.",
                                "properties": {
                                  "name_score": {
                                    "type": "integer",
                                    "nullable": true,
                                    "description": "Kemiripan nama mentah (0–100)."
                                  },
                                  "name_weight": {
                                    "type": "integer",
                                    "nullable": true,
                                    "description": "Bobot nama yang dikonfigurasi (`aml_name_weight`)."
                                  },
                                  "name_weight_normalized": {
                                    "type": "number",
                                    "nullable": true,
                                    "description": "Bobot nama setelah normalisasi ulang (0–100)."
                                  },
                                  "name_contribution": {
                                    "type": "number",
                                    "nullable": true,
                                    "description": "Poin yang dikontribusikan nama ke `total_score`."
                                  },
                                  "dob_score": {
                                    "type": "integer",
                                    "nullable": true,
                                    "description": "Skor tanggal lahir sebagai persentase dari bobotnya (−100 hingga 100)."
                                  },
                                  "dob_weight": {
                                    "type": "integer",
                                    "nullable": true,
                                    "description": "Bobot tanggal lahir yang dikonfigurasi (`aml_dob_weight`)."
                                  },
                                  "dob_weight_normalized": {
                                    "type": "number",
                                    "nullable": true,
                                    "description": "Bobot DOB setelah normalisasi ulang (0–100)."
                                  },
                                  "dob_contribution": {
                                    "type": "number",
                                    "nullable": true,
                                    "description": "Poin yang dikontribusikan tanggal lahir ke `total_score`."
                                  },
                                  "country_score": {
                                    "type": "integer",
                                    "nullable": true,
                                    "description": "Skor negara sebagai persentase dari bobotnya (−100 hingga 100)."
                                  },
                                  "country_weight": {
                                    "type": "integer",
                                    "nullable": true,
                                    "description": "Bobot negara yang dikonfigurasi (`aml_country_weight`)."
                                  },
                                  "country_weight_normalized": {
                                    "type": "number",
                                    "nullable": true,
                                    "description": "Bobot negara setelah normalisasi ulang (0–100)."
                                  },
                                  "country_contribution": {
                                    "type": "number",
                                    "nullable": true,
                                    "description": "Poin yang dikontribusikan negara ke `total_score`."
                                  },
                                  "document_number_match_type": {
                                    "type": "string",
                                    "nullable": true,
                                    "enum": [
                                      "MATCH",
                                      "NEUTRAL",
                                      "HARD_MISMATCH"
                                    ],
                                    "description": "Hasil golden-key untuk perbandingan nomor dokumen."
                                  },
                                  "document_number_effect": {
                                    "type": "string",
                                    "nullable": true,
                                    "description": "Deskripsi pengaruh nomor dokumen yang mudah dibaca manusia."
                                  },
                                  "total_score": {
                                    "type": "integer",
                                    "nullable": true,
                                    "description": "Skor kecocokan berbobot akhir (0–100) — mencerminkan `match_score`."
                                  }
                                }
                              }
                            }
                          }
                        },
                        "score": {
                          "type": "number",
                          "nullable": true,
                          "description": "Skor risiko AML keseluruhan (0–100): `risk_score` tertinggi di antara hit yang bukan Positif Palsu. Menentukan `status` melalui kedua ambang batas."
                        },
                        "screened_data": {
                          "type": "object",
                          "description": "Menampilkan kembali apa yang diskrining: `full_name`, `date_of_birth`, `nationality`, `document_number` (kolom yang tidak ada bernilai `null`).",
                          "properties": {
                            "full_name": {
                              "type": "string"
                            },
                            "date_of_birth": {
                              "type": "string",
                              "nullable": true
                            },
                            "nationality": {
                              "type": "string",
                              "nullable": true
                            },
                            "document_number": {
                              "type": "string",
                              "nullable": true
                            }
                          }
                        },
                        "warnings": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "feature": {
                                "type": "string",
                                "description": "Fitur yang memunculkan peringatan."
                              },
                              "risk": {
                                "type": "string",
                                "description": "Pengidentifikasi risiko yang dapat dibaca mesin."
                              },
                              "additional_data": {
                                "type": "object",
                                "nullable": true,
                                "description": "Konteks tambahan untuk peringatan, jika tersedia."
                              },
                              "log_type": {
                                "type": "string",
                                "description": "`warning`, `information`, atau `error` — pengaruh risiko terhadap hasilnya."
                              },
                              "short_description": {
                                "type": "string",
                                "description": "Ringkasan satu baris yang dapat dibaca manusia."
                              },
                              "long_description": {
                                "type": "string",
                                "description": "Penjelasan lengkap yang dapat dibaca manusia."
                              }
                            }
                          },
                          "description": "Berisi peringatan `POSSIBLE_MATCH_FOUND` setiap kali `score` bernilai bukan nol dan ≥ `aml_score_approve_threshold` (skor tepat 0 tidak pernah memicu peringatan); kosong jika sebaliknya."
                        }
                      }
                    },
                    "vendor_data": {
                      "type": "string",
                      "nullable": true,
                      "description": "Menampilkan kembali `vendor_data` yang Anda kirimkan."
                    },
                    "metadata": {
                      "type": "object",
                      "nullable": true,
                      "description": "Salinan `metadata` yang Anda kirimkan."
                    },
                    "created_at": {
                      "type": "string",
                      "format": "date-time"
                    }
                  }
                },
                "examples": {
                  "No hits (Approved)": {
                    "summary": "Skrining bersih — nol kecocokan",
                    "value": {
                      "request_id": "d27c5509-7a66-45a9-b05e-d69d9f4c336a",
                      "aml": {
                        "status": "Approved",
                        "total_hits": 0,
                        "entity_type": "person",
                        "hits": [],
                        "score": 0,
                        "screened_data": {
                          "full_name": "Maximilian Mustermann-Doe",
                          "date_of_birth": "1992-03-14",
                          "nationality": "DE",
                          "document_number": null
                        },
                        "warnings": []
                      },
                      "vendor_data": "user-1234",
                      "metadata": {
                        "internal_ref": "abc-123"
                      },
                      "created_at": "2026-06-11T10:21:07.013938+00:00"
                    }
                  },
                  "PEP hit (Approved — risk below approve threshold)": {
                    "summary": "Satu kemungkinan kecocokan PEP; skor risiko 73 tetap berada di bawah ambang batas persetujuan default yaitu 80",
                    "value": {
                      "request_id": "0b7e7a3e-65a1-4f3d-9c7a-1de2f9a40111",
                      "aml": {
                        "status": "Approved",
                        "total_hits": 1,
                        "entity_type": "person",
                        "hits": [
                          {
                            "id": "hit_7c1e9a40b2d35f86e0a4c912",
                            "url": "https://news.example.org/articles/sample",
                            "match": false,
                            "score": 0.93,
                            "match_score": 93.0,
                            "risk_score": 73.0,
                            "target": null,
                            "caption": "Antonio Ejemplo Modelo",
                            "datasets": [
                              "PEP Level 1",
                              "PEP"
                            ],
                            "features": null,
                            "rca_name": "",
                            "first_seen": "2026-01-07T00:00:00",
                            "last_seen": "2026-01-07T00:00:00",
                            "review_status": "Unreviewed",
                            "properties": {
                              "name": [
                                "Antonio Ejemplo Modelo",
                                "Antonio Ejemplo"
                              ],
                              "alias": [
                                "Antonio Ejemplo Modelo",
                                "Ejemplo Modelo, Pedro"
                              ],
                              "notes": [
                                "Prime Minister of Spain"
                              ],
                              "gender": [
                                "male"
                              ],
                              "birthDate": [
                                "1972-02-29"
                              ],
                              "birthPlace": [
                                "Madrid, Spain"
                              ],
                              "nationality": null,
                              "position": null
                            },
                            "risk_view": {
                              "crimes": {
                                "score": 0.0,
                                "weightage": 20,
                                "risk_level": "Low",
                                "risk_scores": {}
                              },
                              "countries": {
                                "score": 9.64,
                                "weightage": 30,
                                "risk_level": "Low",
                                "risk_scores": {
                                  "Spain": 25.71
                                }
                              },
                              "categories": {
                                "score": 62.5,
                                "weightage": 50,
                                "risk_level": "High",
                                "risk_scores": {
                                  "PEP": 100.0,
                                  "PEP Level 1": 100.0
                                }
                              },
                              "custom_list": {}
                            },
                            "score_breakdown": {
                              "name_score": 89,
                              "name_weight": 60,
                              "name_weight_normalized": 60.0,
                              "name_contribution": 53.4,
                              "dob_score": 100,
                              "dob_weight": 25,
                              "dob_weight_normalized": 25.0,
                              "dob_contribution": 25.0,
                              "country_score": 100,
                              "country_weight": 15,
                              "country_weight_normalized": 15.0,
                              "country_contribution": 15.0,
                              "document_number_match_type": "NEUTRAL",
                              "document_number_effect": "No document number provided for screening",
                              "total_score": 93
                            },
                            "pep_matches": [
                              {
                                "aliases": [],
                                "education": [],
                                "list_name": "Presidency of the Government of Spain",
                                "publisher": "Presidency of the Government of Spain",
                                "source_url": "https://news.example.org/articles/sample",
                                "description": "The Presidency of the Government is the central institutional body in Spain that supports the Prime Minister and coordinates the general action of the central government.",
                                "matched_name": "Antonio Ejemplo Modelo",
                                "pep_position": "",
                                "date_of_birth": "1972-02-29",
                                "other_sources": [],
                                "place_of_birth": "Madrid, Spain"
                              }
                            ],
                            "sanction_matches": [],
                            "warning_matches": [],
                            "adverse_media_matches": [],
                            "adverse_media_details": null,
                            "linked_entities": [
                              {
                                "name": [
                                  "Maria Begona Gomez Fernandez"
                                ],
                                "active": [],
                                "status": [],
                                "details": [],
                                "relation": [
                                  "spouse"
                                ]
                              }
                            ],
                            "additional_information": {
                              "flag_summary": [
                                "Antonio Ejemplo Modelo has been flagged as a Level 1 Politically Exposed Person (PEP) from Spain, serving as the President of the Government of Spain."
                              ]
                            }
                          }
                        ],
                        "score": 73.0,
                        "screened_data": {
                          "full_name": "Pedro Sanchez Perez-Castejon",
                          "date_of_birth": "1972-02-29",
                          "nationality": "ES",
                          "document_number": null
                        },
                        "warnings": []
                      },
                      "vendor_data": null,
                      "metadata": null,
                      "created_at": "2026-06-11T10:23:44.812000+00:00"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Kesalahan validasi. Masalah tingkat kolom mengembalikan format standar DRF (satu larik pesan per kolom yang bermasalah); aturan lintas kolom (jumlah bobot, pengurutan ambang batas, pemantauan tanpa penyimpanan) mengembalikan `{\"error\": [...]}`.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing full_name": {
                    "summary": "`full_name` adalah satu-satunya kolom yang wajib diisi",
                    "value": {
                      "full_name": [
                        "This field is required."
                      ]
                    }
                  },
                  "Short full_name": {
                    "summary": "`full_name` harus memiliki minimal 2 karakter",
                    "value": {
                      "full_name": [
                        "Ensure this field has at least 2 characters."
                      ]
                    }
                  },
                  "Invalid nationality": {
                    "summary": "`nationality` harus berupa ISO 3166-1 alpha-2",
                    "value": {
                      "nationality": [
                        "Invalid ISO 3166-1 alpha-2 country code."
                      ]
                    }
                  },
                  "Weights do not sum to 100": {
                    "summary": "`aml_name_weight` + `aml_dob_weight` + `aml_country_weight` ≠ 100",
                    "value": {
                      "error": [
                        "AML weights must sum to 100. Current sum: 90 (name: 50, dob: 25, country: 15)"
                      ]
                    }
                  },
                  "Thresholds out of order": {
                    "summary": "Ambang batas persetujuan di atas ambang batas peninjauan",
                    "value": {
                      "error": [
                        "Approve threshold (90.0) cannot be greater than review threshold (80.0)"
                      ]
                    }
                  },
                  "Monitoring without saving": {
                    "summary": "`include_ongoing_monitoring=true` dengan `save_api_request=false`",
                    "value": {
                      "error": [
                        "Ongoing monitoring can only be enabled when the API request is saved."
                      ]
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Izin ditolak. Dikembalikan ketika header `x-api-key` tidak ada, dan juga ketika saldo organisasi pemanggil tidak dapat mencukupi biaya panggilan tersebut; kunci yang salah, dicabut, atau kedaluwarsa mengembalikan `401`. Kunci yang tidak ada mengembalikan `403` dengan `{\"detail\": ...}`; kunci yang salah, dicabut, atau kedaluwarsa mengembalikan `401`. Kekurangan kredit mengembalikan `403` dengan `{\"error\": ...}` sebelum skrining atau panggilan penyedia apa pun terjadi.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing or invalid API key": {
                    "summary": "Tidak ada header `x-api-key`, atau kuncinya tidak valid/dicabut",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Not enough credits": {
                    "summary": "Saldo organisasi tidak mencukupi untuk panggilan ini",
                    "value": {
                      "error": "You don't have enough credits to perform this request. Please top up at https://business.didit.me"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Batas laju terlampaui. Endpoint POST/PATCH/DELETE berbagi anggaran 300 permintaan penulisan per menit per kunci API (pembuatan transaksi dan ingesti event memiliki anggaran terpisah sebesar 600). Respons menyertakan header `X-RateLimit-Limit`, `X-RateLimit-Remaining`, `X-RateLimit-Reset`, dan `Retry-After`.",
            "content": {
              "application/json": {
                "examples": {
                  "Write rate limit exceeded": {
                    "summary": "Lebih dari 300 permintaan tulis pada menit ini",
                    "value": {
                      "detail": "Write request rate limit exceeded. You can make up to 300 requests per minute."
                    }
                  }
                },
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v3/face-search/": {
      "post": {
        "summary": "Pencarian Wajah",
        "description": "Cari gambar wajah (1:N) terhadap indeks pencarian wajah aplikasi Anda — wajah yang didaftarkan dari sesi verifikasi, panggilan API mandiri yang disimpan, unggahan langsung wajah dari profil pengguna, serta daftar blokir/izin Anda — dan dapatkan kecocokan kemiripan berperingkat beserta peringatan daftar blokir dan duplikat.\n\n**Cara kerjanya.** Wajah terbesar yang terdeteksi di `user_image` di-embed dan dicari terhadap indeks, yang dibatasi pada aplikasi Anda. Hingga **5 kecocokan** di atas ambang batas kemiripan minimum dikembalikan di `matches`, masing-masing dengan `similarity_percentage`, sesi asal (`session_id`, `session_number`, `status`, `vendor_data`), `user_details` yang diekstrak selama verifikasi dokumen sesi tersebut, penanda `is_blocklisted` / `is_allowlisted`, dan pembeda `source` (`session`, `imported`, atau `list_entry`).\n\n- `search_type=most_similar` (default) memberi peringkat setiap wajah yang terdaftar berdasarkan kemiripan — gunakan ini untuk deduplikasi dan penyelidikan sindikat penipuan.\n- `search_type=blocklisted_or_approved` membatasi kandidat pada wajah yang masuk daftar blokir, wajah yang masuk daftar izin, wajah dari sesi yang disetujui, dan wajah profil pengguna yang diimpor, dengan memberi peringkat entri daftar blokir terlebih dahulu — gunakan ini ketika tujuan utamanya adalah skrining daftar blokir.\n\n`status` bernilai `Declined` hanya ketika peringatan `FACE_IN_BLOCKLIST` atau `POSSIBLE_FACE_IN_BLOCKLIST` terpicu; `DUPLICATED_FACE` / `POSSIBLE_DUPLICATED_FACE` (`information`) dan `MULTIPLE_FACES_DETECTED` (`warning`) tidak pernah menolak. Tidak seperti Passive Liveness, endpoint ini **tidak** mengecualikan sesi sebelumnya dengan `vendor_data` yang sama dari pencocokan. Analisis passive liveness juga berjalan secara internal dan disimpan bersama sesi yang disimpan, tetapi hasilnya bukan bagian dari respons ini.\n\n**Penagihan.** Setiap respons `200` mengonsumsi satu kredit API Face Search (dibayar dari kredit paket atau saldo isi ulang Anda). Saldo yang tidak mencukupi akan mengembalikan `403` sebelum pemrosesan gambar apa pun.\n\n**Persistensi sesi dan pendaftaran wajah (`save_api_request`, default `true`).** Jika bernilai `true`, panggilan tersebut akan disimpan sebagai sesi bertipe API (Business Console, `GET /v3/session/{sessionId}/decision/` melalui `request_id` yang dikembalikan, webhook `status.updated`) dan wajah yang dicari akan didaftarkan ke dalam indeks pencarian wajah Anda. Wajah yang didaftarkan melalui panggilan Face Search dikecualikan dari hasil Face Search mendatang, sehingga pencarian berulang tidak akan pernah saling cocok. Jika bernilai `false`, panggilan bersifat sekali pakai: tidak ada yang disimpan, wajah tidak didaftarkan, dan nilai `match_image_url` merupakan jalur penyimpanan internal alih-alih URL yang dapat diunduh.\n\n**Sandbox.** Kunci API sandbox melewati semua pemrosesan dan penagihan: setelah validasi permintaan (input yang salah format tetap mengembalikan `400`), endpoint mengembalikan payload tiruan `Approved` statis, tidak ada sesi yang disimpan, dan tidak ada kredit yang digunakan.\n\n**Autentikasi.** Kirim kunci API aplikasi Anda di header `x-api-key`. Kredensial yang hilang atau tidak valid akan mengembalikan `403` (`{\"detail\": \"You do not have permission to perform this action.\"}`) — API ini tidak pernah mengembalikan `401`.\n\n**Batas laju.** Anggaran tulis bersama sebesar 300 permintaan/menit per kunci API di semua endpoint POST/PATCH/DELETE; melebihi batas ini akan mengembalikan `429`.",
        "operationId": "post_v3face-search",
        "x-didit-sdk": {
          "resource": "face_search",
          "method": "search",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Standalone APIs"
        ],
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "required": [
                  "user_image"
                ],
                "properties": {
                  "user_image": {
                    "type": "string",
                    "format": "binary",
                    "description": "Gambar wajah menghadap ke depan yang digunakan untuk pencarian. Ekstensi yang diizinkan: `tiff`, `jpg`, `jpeg`, `png`, `webp`. Ukuran unggah maksimum: **5 MB** (berkas yang lebih besar ditolak dengan kode `400`). Gambar dikompresi secara otomatis menjadi ~0.5 MB sebelum diproses, sehingga resolusi yang sangat tinggi tidak meningkatkan akurasi. Gambar harus berisi setidaknya satu wajah yang dapat dideteksi — jika tidak, endpoint akan mengembalikan kode `400`. Jika terdapat beberapa wajah, wajah terbesar yang akan dicari dan peringatan `MULTIPLE_FACES_DETECTED` akan ditambahkan."
                  },
                  "search_type": {
                    "type": "string",
                    "default": "most_similar",
                    "enum": [
                      "most_similar",
                      "blocklisted_or_approved"
                    ],
                    "description": "Kebijakan pencarian. `most_similar` (default) mengurutkan setiap wajah yang terdaftar di aplikasi Anda berdasarkan kemiripan. `blocklisted_or_approved` membatasi kandidat ke wajah yang masuk daftar blokir, wajah yang masuk daftar izin, wajah dari sesi yang disetujui, dan wajah profil pengguna yang diimpor — dengan entri daftar blokir diurutkan terlebih dahulu.",
                    "example": "most_similar"
                  },
                  "rotate_image": {
                    "type": "boolean",
                    "default": false,
                    "description": "Jika `true`, layanan mencoba rotasi 90 derajat dari input dan menggunakan orientasi yang menghasilkan deteksi wajah terbaik. Berguna saat orientasi EXIF tidak ada. Menambah latensi.",
                    "example": false
                  },
                  "save_api_request": {
                    "type": "boolean",
                    "default": true,
                    "description": "Jika `true` (default), menyimpan panggilan sebagai sesi tipe API, memancarkan webhook `status.updated`, melakukan pra-penandatanganan nilai `match_image_url`, dan mendaftarkan wajah yang dicari ke dalam indeks pencarian wajah Anda (pendaftaran Pencarian Wajah dikecualikan dari pencarian mendatang). Jika `false`, pencarian bersifat sekali jalan — tidak ada sesi yang disimpan dan wajah tidak didaftarkan.",
                    "example": true
                  },
                  "vendor_data": {
                    "type": "string",
                    "description": "Pengidentifikasi buram opsional (ID pengguna, email, UUID Anda…) yang disimpan pada sesi yang dipertahankan dan dikembalikan. Kolom ini tidak mengecualikan wajah pengguna yang sama dari hasil pencarian.",
                    "example": "user-123"
                  },
                  "metadata": {
                    "type": "object",
                    "additionalProperties": true,
                    "description": "Objek JSON opsional yang disimpan bersama sesi (saat `save_api_request=true`) dan dikembalikan. Dalam permintaan multipart, kirimkan sebagai kolom string berenkode JSON — kolom ini akan diuraikan menjadi sebuah objek.",
                    "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": "Pencarian wajah selesai. `face_search.matches` memuat hingga 5 wajah serupa yang diurutkan berdasarkan kemiripan; array kosong berarti tidak ada wajah terdaftar yang melampaui batas minimum kemiripan. `status` bernilai `Declined` hanya pada kecocokan daftar blokir — kecocokan duplikat saja mengembalikan `Approved`, jadi periksa `matches` dan `warnings`, bukan hanya `status`. Ketika `save_api_request=true`, `request_id` adalah id sesi yang disimpan. Setiap kecocokan membawa `source` (`session`, `imported`, `list_entry`, atau `retained_template`), `vendor_user_id`, dan `biometric_template_id`; kecocokan `retained_template` berasal dari templat biometrik bebas gambar yang disimpan setelah sesi sumber dihapus dan memiliki kolom sesi `null`, `match_image_url`, dan `user_details`.",
            "content": {
              "application/json": {
                "examples": {
                  "Blocklist hit (Declined)": {
                    "summary": "Wajah cocok dengan wajah yang ada di daftar blokir",
                    "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": "Wajah sudah muncul di sesi lain yang disetujui — bersifat informasi, tidak ditolak",
                    "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": "Tidak ada wajah terdaftar yang melampaui batas minimum kemiripan",
                    "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": "ID sesi yang disimpan saat `save_api_request=true` (dapat digunakan dengan `GET /v3/session/{sessionId}/decision/`); jika tidak, berupa UUID korelasi sementara."
                    },
                    "face_search": {
                      "type": "object",
                      "properties": {
                        "status": {
                          "type": "string",
                          "enum": [
                            "Approved",
                            "Declined"
                          ],
                          "description": "`Declined` hanya ketika peringatan `FACE_IN_BLOCKLIST` atau `POSSIBLE_FACE_IN_BLOCKLIST` terpicu. Kecocokan duplikat dan peringatan banyak wajah tidak pernah menolak."
                        },
                        "total_matches": {
                          "type": "integer",
                          "description": "Jumlah entri dalam `matches` (0–5).",
                          "example": 1
                        },
                        "matches": {
                          "type": "array",
                          "maxItems": 5,
                          "description": "Hingga 5 wajah dari indeks pencarian wajah Anda yang melebihi ambang batas kemiripan, diurutkan berdasarkan kemiripan (dengan entri daftar blokir diperingkat pertama ketika `search_type=blocklisted_or_approved`). Kosong jika tidak ada wajah terdaftar yang cukup mirip.",
                          "items": {
                            "type": "object",
                            "properties": {
                              "session_id": {
                                "type": "string",
                                "format": "uuid",
                                "nullable": true,
                                "description": "ID sesi verifikasi tempat wajah yang cocok berada. Bernilai `null` jika `source` adalah `imported`, `list_entry`, atau `retained_template`.",
                                "example": "882c42d5-8a4d-4d20-8080-a22f57822c86"
                              },
                              "session_number": {
                                "type": "integer",
                                "nullable": true,
                                "description": "Nomor sesi yang mudah dibaca manusia yang ditampilkan di Business Console. `null` untuk kecocokan non-sesi.",
                                "example": 323442
                              },
                              "similarity_percentage": {
                                "type": "number",
                                "format": "float",
                                "minimum": 0,
                                "maximum": 100,
                                "description": "Kemiripan antara wajah yang dikirimkan dan wajah yang cocok (0–100).",
                                "example": 99.99
                              },
                              "source": {
                                "type": "string",
                                "enum": [
                                  "session",
                                  "imported",
                                  "list_entry",
                                  "retained_template"
                                ],
                                "description": "Asal pendaftaran wajah yang cocok: `session` — sesi verifikasi atau panggilan API mandiri yang disimpan; `imported` — wajah yang diunggah langsung ke profil Pengguna; `list_entry` — wajah yang dilampirkan ke salah satu daftar Anda; `retained_template` — templat biometrik bebas gambar yang disimpan pada Pengguna, tercantum di bawah `/v3/biometric-templates/`."
                              },
                              "vendor_data": {
                                "type": "string",
                                "nullable": true,
                                "description": "`vendor_data` dari sesi yang cocok atau Pengguna yang ditautkan untuk wajah yang diimpor dan templatnya dipertahankan.",
                                "example": "user-1"
                              },
                              "vendor_user_id": {
                                "type": "string",
                                "format": "uuid",
                                "nullable": true,
                                "description": "ID Pengguna yang ditautkan. `null` untuk entri daftar dan kecocokan sesi tanpa Pengguna.",
                                "example": "2f7c1a9e-4b28-4a6d-97f1-83576f80e1b4"
                              },
                              "biometric_template_id": {
                                "type": "string",
                                "format": "uuid",
                                "nullable": true,
                                "description": "Id templat biometrik yang disimpan. Ditetapkan hanya jika `source` bernilai `retained_template`; jika tidak, bernilai `null`.",
                                "example": null
                              },
                              "verification_date": {
                                "type": "string",
                                "format": "date-time",
                                "nullable": true,
                                "description": "Waktu wajah yang cocok awalnya diambil, atau waktu templat yang disimpan dibuat (`YYYY-MM-DDThh:mm:ssZ`). `null` untuk kecocokan `list_entry`.",
                                "example": "2025-01-01T00:00:00Z"
                              },
                              "user_details": {
                                "type": "object",
                                "nullable": true,
                                "description": "Data identitas yang diekstrak selama verifikasi dokumen sesi yang cocok. Bernilai `null` jika sesi yang cocok tidak memiliki data dokumen (misalnya sesi khusus liveness) dan selalu bernilai `null` untuk kecocokan `retained_template`. Untuk kecocokan `source: imported`, nilai diisi dari profil Pengguna: `full_name` terisi, `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 dengan batas waktu (`https://<media-host>/...`) dari gambar referensi wajah yang cocok saat `save_api_request=true`. Jika `save_api_request=false`, ini adalah jalur penyimpanan internal yang tidak dapat diunduh secara langsung. Selalu `null` untuk kecocokan `retained_template` karena templat yang disimpan tidak berisi gambar.",
                                "example": "https://<media-host>/face/3f6a1c2e/reference.jpg"
                              },
                              "status": {
                                "type": "string",
                                "nullable": true,
                                "description": "Status sesi yang cocok (`Approved`, `Declined`, `In Review`, …). `null` untuk kecocokan `imported`/`list_entry`.",
                                "example": "Approved"
                              },
                              "is_blocklisted": {
                                "type": "boolean",
                                "description": "`true` saat wajah yang cocok ada di daftar blokir wajah Anda. Setiap kecocokan daftar blokir yang cukup mirip akan menolak pencarian."
                              },
                              "is_allowlisted": {
                                "type": "boolean",
                                "description": "`true` saat wajah yang cocok berada di salah satu daftar izin Anda. Kecocokan yang masuk daftar izin akan meniadakan peringatan duplikat."
                              },
                              "api_service": {
                                "type": "string",
                                "nullable": true,
                                "description": "Ditetapkan saat wajah yang cocok didaftarkan melalui panggilan API mandiri (misalnya `PASSIVE_LIVENESS`); bernilai `null` untuk sesi verifikasi reguler dan wajah yang diimpor.",
                                "example": null
                              }
                            }
                          }
                        },
                        "user_image": {
                          "type": "object",
                          "description": "Hasil deteksi wajah untuk gambar yang dikirimkan. Entri di sini hanya membawa `bbox` dan `confidence`.",
                          "properties": {
                            "entities": {
                              "type": "array",
                              "description": "Satu entri per wajah yang terdeteksi. Wajah terbesar adalah wajah yang dicari.",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "bbox": {
                                    "type": "array",
                                    "items": {
                                      "type": "integer"
                                    },
                                    "minItems": 4,
                                    "maxItems": 4,
                                    "description": "Bounding box `[x_min, y_min, x_max, y_max]` dalam piksel.",
                                    "example": [
                                      40,
                                      40,
                                      120,
                                      120
                                    ]
                                  },
                                  "confidence": {
                                    "type": "number",
                                    "format": "float",
                                    "minimum": 0,
                                    "maximum": 1,
                                    "description": "Skor keyakinan deteksi wajah (0–1).",
                                    "example": 0.732973
                                  }
                                }
                              }
                            },
                            "best_angle": {
                              "type": "integer",
                              "description": "Rotasi (derajat) yang menghasilkan deteksi wajah terbaik; bernilai bukan nol hanya ketika `rotate_image=true` mengoreksi orientasi. Tidak pernah null pada endpoint ini (default ke 0 ketika model menghilangkannya).",
                              "example": 0
                            }
                          }
                        },
                        "warnings": {
                          "type": "array",
                          "description": "Sinyal risiko. `FACE_IN_BLOCKLIST` / `POSSIBLE_FACE_IN_BLOCKLIST` (`error`) menolak pencarian; `MULTIPLE_FACES_DETECTED` (`warning`) dan `DUPLICATED_FACE` / `POSSIBLE_DUPLICATED_FACE` (`information`) bersifat informatif.",
                          "items": {
                            "type": "object",
                            "properties": {
                              "risk": {
                                "type": "string",
                                "enum": [
                                  "MULTIPLE_FACES_DETECTED",
                                  "FACE_IN_BLOCKLIST",
                                  "POSSIBLE_FACE_IN_BLOCKLIST",
                                  "DUPLICATED_FACE",
                                  "POSSIBLE_DUPLICATED_FACE"
                                ],
                                "description": "Kode risiko yang dapat dibaca mesin."
                              },
                              "feature": {
                                "type": "string",
                                "enum": [
                                  "LIVENESS"
                                ],
                                "description": "Fitur yang memunculkan peringatan. Selalu `LIVENESS` pada endpoint ini."
                              },
                              "additional_data": {
                                "type": "object",
                                "nullable": true,
                                "additionalProperties": true,
                                "description": "`null` untuk `MULTIPLE_FACES_DETECTED`. Hasil yang cocok dengan daftar blokir berisi `{blocklisted_session_id, blocklisted_session_number, api_service}`; hasil duplikat berisi `{duplicated_session_id, duplicated_session_number, api_service}` yang mengarah ke sesi pertama yang cocok."
                              },
                              "log_type": {
                                "type": "string",
                                "enum": [
                                  "error",
                                  "warning",
                                  "information"
                                ],
                                "description": "Tingkat keparahan. Peringatan `error` mendorong `status` menjadi `Declined`; entri `warning` dan `information` bersifat anjuran dan tidak pernah menolak dengan sendirinya."
                              },
                              "short_description": {
                                "type": "string",
                                "description": "Ringkasan satu baris yang dapat dibaca manusia tentang risiko."
                              },
                              "long_description": {
                                "type": "string",
                                "description": "Penjelasan risiko yang mudah dibaca manusia."
                              }
                            }
                          }
                        }
                      }
                    },
                    "vendor_data": {
                      "type": "string",
                      "nullable": true,
                      "description": "Salinan `vendor_data` yang Anda kirimkan, atau `null`."
                    },
                    "metadata": {
                      "type": "object",
                      "nullable": true,
                      "additionalProperties": true,
                      "description": "Salinan objek `metadata` yang Anda kirimkan, atau `null`."
                    },
                    "created_at": {
                      "type": "string",
                      "format": "date-time",
                      "description": "Stempel waktu ISO 8601 (UTC) saat respons dibuat, misalnya `2026-06-12T01:04:42.763237+00:00`."
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Kesalahan validasi. Dikembalikan ketika `user_image` tidak ada, melebihi 5 MB, memiliki ekstensi yang tidak didukung, atau ketika **tidak ada wajah yang terdeteksi** pada gambar yang dikirimkan. Kesalahan kolom menggunakan envelope `{field: [messages]}` milik DRF; kegagalan deteksi wajah menggunakan `{\"error\": ...}`.",
            "content": {
              "application/json": {
                "examples": {
                  "No face detected": {
                    "summary": "Gambar dapat didekode dengan baik tetapi tidak berisi wajah yang dapat dideteksi",
                    "value": {
                      "error": "No face detected in the image"
                    }
                  },
                  "Missing image": {
                    "summary": "`user_image` tidak disertakan dalam data formulir",
                    "value": {
                      "user_image": [
                        "No file was submitted."
                      ]
                    }
                  },
                  "Unsupported file extension": {
                    "summary": "Ekstensi file di luar 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": "Unggahan melebihi batas 5 MB",
                    "value": {
                      "user_image": [
                        "File size should not exceed 5 MB"
                      ]
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Izin ditolak. Dikembalikan ketika header `x-api-key` tidak ada, dan juga ketika saldo organisasi pemanggil tidak dapat mencukupi biaya panggilan tersebut; kunci yang salah, dicabut, atau kedaluwarsa mengembalikan `401`. Kunci yang tidak ada mengembalikan `403` dengan `{\"detail\": ...}`; kunci yang salah, dicabut, atau kedaluwarsa mengembalikan `401`. Kekurangan kredit mengembalikan `403` dengan `{\"error\": ...}` sebelum pemrosesan gambar apa pun terjadi.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing or invalid API key": {
                    "summary": "Tidak ada header `x-api-key`, atau kuncinya tidak valid/dicabut",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Not enough credits": {
                    "summary": "Saldo organisasi tidak mencukupi untuk panggilan ini",
                    "value": {
                      "error": "You don't have enough credits to perform this request. Please top up at https://business.didit.me"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Batas laju terlampaui. Endpoint POST/PATCH/DELETE berbagi anggaran 300 permintaan penulisan per menit per kunci API (pembuatan transaksi dan ingesti event memiliki anggaran terpisah sebesar 600). Respons menyertakan header `X-RateLimit-Limit`, `X-RateLimit-Remaining`, `X-RateLimit-Reset`, dan `Retry-After`.",
            "content": {
              "application/json": {
                "examples": {
                  "Write rate limit exceeded": {
                    "summary": "Lebih dari 300 permintaan tulis pada menit ini",
                    "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/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -F 'user_image=@./selfie.jpg' \\\n  -F 'search_type=most_similar' \\\n  -F 'save_api_request=true' \\\n  -F 'vendor_data=user-123'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.face_search.search(\n    user_image=open(\"user_image.jpg\", \"rb\"),\n    search_type=\"most_similar\",\n    rotate_image=False,\n    save_api_request=True,\n    vendor_data=\"user-123\",\n    metadata={\"flow\": \"dedup_check\"},\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit, { fileFromPath } from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.faceSearch.search({\n  user_image: await fileFromPath(\"user_image.jpg\"),\n  search_type: \"most_similar\",\n  rotate_image: false,\n  save_api_request: true,\n  vendor_data: \"user-123\",\n  metadata: { flow: \"dedup_check\" },\n});\nconsole.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;\nimport java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.FaceSearchSearchParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.faceSearch().search(FaceSearchSearchParams.builder()\n        .userImage(Path.of(\"user_image.jpg\"))\n        .searchType(FaceSearchSearchParams.SearchType.of(\"most_similar\"))\n        .rotateImage(false)\n        .saveApiRequest(true)\n        .vendorData(\"user-123\")\n        .metadata(Map.of(\"flow\", \"dedup_check\"))\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\nuse Didit\\File;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->faceSearch->search([\n    'user_image' => File::fromPath('user_image.jpg'),\n    'search_type' => 'most_similar',\n    'rotate_image' => false,\n    'save_api_request' => true,\n    'vendor_data' => 'user-123',\n    'metadata' => ['flow' => 'dedup_check'],\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.face_search.search(\n  user_image: Pathname(\"user_image.jpg\"),\n  search_type: \"most_similar\",\n  rotate_image: false,\n  save_api_request: true,\n  vendor_data: \"user-123\",\n  metadata: { flow: \"dedup_check\" }\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.FaceSearch.SearchAsync(new FaceSearchSearchParams\n{\n    UserImage = FileUpload.FromPath(\"user_image.jpg\"),\n    SearchType = new FaceSearchSearchParamsSearchType(\"most_similar\"),\n    RotateImage = false,\n    SaveApiRequest = true,\n    VendorData = \"user-123\",\n    Metadata = new Dictionary<string, object> { [\"flow\"] = \"dedup_check\" },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/sessions/": {
      "get": {
        "summary": "Daftar sesi verifikasi (KYC dan/atau KYB) dengan filter dan paginasi",
        "description": "Mengembalikan daftar sesi verifikasi yang dipaginasi untuk aplikasi yang diidentifikasi oleh kunci API Anda, yang terbaru terlebih dahulu (`session_number` menurun).\n\n**URL Kanonis:** rutenya adalah `/v3/sessions/` (garis miring penutup). Permintaan ke `/v3/sessions` tanpa garis miring akan menerima pengalihan `301` ke URL bergaris miring dengan query string yang tetap dipertahankan; sebagian besar klien HTTP mengikutinya secara transparan pada GET.\n\n**Kapan menggunakan endpoint ini vs webhook.** Gunakan endpoint ini untuk dasbor, pencarian back-office, rekonsiliasi, dan ekspor batch. Jangan melakukan polling untuk melacak progres verifikasi individual - sebagai gantinya, konfigurasikan [webhook](/id/integration/webhooks), yang mengirimkan event `status.updated` tepat saat sesi berubah. Untuk hasil lengkap satu sesi, panggil `GET /v3/session/{sessionId}/decision/`.\n\n**Sesi KYC dan KYB.** `session_kind` memilih jenis mana yang dicantumkan:\n- `user` (default) - Sesi Verifikasi Pengguna (KYC) saja. Perilaku yang kompatibel dengan versi sebelumnya.\n- `business` - Sesi Verifikasi Bisnis (KYB) saja. Baris memiliki bentuk yang berbeda dan lebih ringkas (lihat skema respons).\n- `all` - kedua jenis dalam satu respons: halaman KYC dan halaman KYB untuk `limit`/`offset` yang sama digabungkan dalam `results` (baris KYC terlebih dahulu), sehingga satu halaman dapat berisi hingga `2 x limit` baris. `count` adalah jumlah dari kedua jenis dan `next`/`previous` mencerminkan paginasi sisi KYC. Untuk paginasi data campuran yang ketat, panggil `user` dan `business` secara terpisah.\n\nSetiap baris membawa diskriminator `session_kind` (`\"user\"` atau `\"business\"`).\n\n**Paginasi.** Limit/offset standar: `limit` (default 50) dan `offset` (default 0), dengan URL halaman siap pakai `next`/`previous`. Untuk baris KYC, `count` bersifat tepat. Untuk baris KYB, `count` dihitung dengan pemindaian terbatas dan dibatasi maksimal 100 - ketika ada lebih dari 100 kecocokan, nilainya tetap 100, jadi lakukan iterasi menggunakan `next` (atau dengan memeriksa apakah halaman penuh dikembalikan) daripada menghitung total halaman dari `count`.\n\n**Semantik filter.** Semua filter digabungkan dengan AND dan berlaku untuk baris KYC. Saat `session_kind` bernilai `business` atau `all`, sisi KYB menerapkan parameter bersama `vendor_data`, `status`, `workflow_id`, `country` (kode negara registri perusahaan), `date_from`, `date_to`, `search` (nama perusahaan, nomor registrasi — ketik nomor registrasi tanpa pemisah, mis. `DPC001` bukan `DPC-001` — vendor_data, nomor sesi, atau UUID sesi), `warning`, dan `organization_name`; filter khusus KYC lainnya diabaikan untuk baris KYB. Parameter yang dipisahkan koma (`status`, `country`, `document_type`, `region`, `workflow_id`, `document_name`, `warning`, `organization_name`, `session_type`) cocok dengan salah satu nilai yang tercantum (OR dalam parameter). `vendor_data` adalah kecocokan persis - gunakan `search` untuk pencocokan parsial. Nilai yang tidak dikenal dalam filter daftar cukup menghasilkan respons tanpa baris (tidak ada error); nilai bertipe data tidak valid (`date_from`, `date_to`, `didit_internal_id`, `api_service`, `session_kind`) mengembalikan `400` dengan objek error per kolom.\n\n**Pencarian.** `search` menyesuaikan dengan input: UUID lengkap mencari `session_id`; digit (dengan opsional `+ - . space`) cocok dengan awalan nomor sesi, nomor dokumen/pribadi, awalan nomor telepon, atau `vendor_data`; nilai yang mengandung `@` cocok dengan awalan email; teks lainnya cocok dengan nama (tidak peka aksen) dan `vendor_data`.\n\nTidak ada batas laju per-endpoint tetap yang diterapkan, tetapi jangan terlalu sering melakukan polling daftar dan andalkan webhook untuk pembaruan real-time.",
        "operationId": "get_v3_sessions",
        "x-didit-sdk": {
          "resource": "sessions",
          "method": "list",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Sessions"
        ],
        "parameters": [
          {
            "name": "session_kind",
            "in": "query",
            "required": false,
            "description": "Jenis sesi mana yang akan dicantumkan: `user` (khusus KYC, default), `business` (khusus KYB), atau `all` (keduanya, digabungkan - lihat deskripsi untuk semantik paginasi gabungan). Pencocokan bersifat tidak peka huruf besar/kecil (`BUSINESS` berfungsi); nilai apa pun selain variasi huruf dari `user`/`business`/`all` akan mengembalikan `400`.",
            "schema": {
              "type": "string",
              "enum": [
                "user",
                "business",
                "all"
              ],
              "default": "user"
            },
            "example": "all"
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Jumlah baris maksimum per halaman (per jenis saat `session_kind=all`). Defaultnya 50.",
            "schema": {
              "type": "integer",
              "default": 50,
              "minimum": 1,
              "maximum": 1000000
            },
            "example": 20
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "description": "Jumlah baris yang dilewati sebelum baris pertama yang dikembalikan. Default-nya 0. Disarankan mengikuti URL `next`/`previous` dari respons.",
            "schema": {
              "type": "integer",
              "default": 0,
              "minimum": 0,
              "maximum": 1000000
            },
            "example": 20
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "description": "Daftar status sesi yang dipisahkan dengan koma untuk disertakan, misalnya `Approved,In Review`. Nilai bersifat case-sensitive; lihat [Status Verifikasi](/id/integration/verification-statuses). Nilai yang tidak dikenal tidak akan cocok dengan apa pun.",
            "schema": {
              "type": "string"
            },
            "example": "Approved,In Review"
          },
          {
            "name": "vendor_data",
            "in": "query",
            "required": false,
            "description": "Filter kecocokan persis pada `vendor_data` yang Anda kirim saat pembuatan sesi (pengenal pengguna/bisnis Anda sendiri). Untuk kecocokan sebagian, gunakan `search` sebagai gantinya.",
            "schema": {
              "type": "string"
            },
            "example": "your-user-id-123"
          },
          {
            "name": "search",
            "in": "query",
            "required": false,
            "description": "Referensi lengkap yang ditampilkan seperti `S-0001` (pengguna) atau `B-0001` (bisnis) hanya cocok dengan nomor dan jenis sesi tersebut; angka nol di awal dan huruf besar/kecil tidak memengaruhi pencocokan. Pencarian teks bebas pintar. UUID lengkap cocok dengan `session_id`; input numerik cocok dengan awalan nomor sesi, nomor dokumen/identitas pribadi, awalan telepon, atau `vendor_data`; input yang memuat `@` cocok dengan awalan email; teks lainnya cocok dengan nama (tidak sensitif aksen) dan `vendor_data`. Teks bebas yang memuat digit juga cocok dengan kolom pencarian nomor dokumen/identitas pribadi dan awalan nomor sesi.",
            "schema": {
              "type": "string"
            },
            "example": "jane doe"
          },
          {
            "name": "workflow_id",
            "in": "query",
            "required": false,
            "description": "UUID alur kerja yang dipisahkan koma (temukan di halaman Alur Kerja di Konsol). UUID yang salah format dalam daftar akan diabaikan; jika tidak ada yang valid, hasilnya kosong.",
            "schema": {
              "type": "string"
            },
            "example": "9f9b1234-aaaa-bbbb-cccc-1234567890ab"
          },
          {
            "name": "date_from",
            "in": "query",
            "required": false,
            "description": "Hanya sesi yang dibuat pada atau setelah tanggal ini (UTC), format `YYYY-MM-DD`. Format tanggal yang salah akan mengembalikan `400`.",
            "schema": {
              "type": "string",
              "format": "date"
            },
            "example": "2026-06-01"
          },
          {
            "name": "date_to",
            "in": "query",
            "required": false,
            "description": "Hanya sesi yang dibuat hingga tanggal ini (UTC), format `YYYY-MM-DD`. Untuk baris KYC, seluruh hari disertakan; untuk baris KYB, perbandingannya adalah `created_at <= date_to` (tengah malam), jadi gunakan tanggal hari berikutnya untuk menyertakan sesi KYB satu hari penuh.",
            "schema": {
              "type": "string",
              "format": "date"
            },
            "example": "2026-06-30"
          },
          {
            "name": "tags",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "ID tag yang dipisahkan dengan koma (`tags` dari aplikasi Anda). Mengembalikan sesi yang memuat salah satu di antaranya. ID yang bukan UUID valid akan diabaikan, dan jika tidak ada yang valid, daftarnya kosong."
          },
          {
            "name": "decided_from",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Tanggal dan waktu ISO 8601. Mengembalikan sesi yang statusnya terakhir berubah pada atau setelah waktu tersebut. Filter ini menyaring berdasarkan waktu perubahan status terakhir, bukan waktu pembuatan."
          },
          {
            "name": "decided_to",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Datetime ISO 8601. Mengembalikan sesi yang statusnya terakhir berubah sebelum waktu tersebut. Gabungkan dengan `decided_from` untuk jendela setengah terbuka."
          },
          {
            "name": "country",
            "in": "query",
            "required": false,
            "description": "Filter negara yang dipisahkan koma. Untuk baris KYC: kode ISO 3166-1 alpha-3 dari negara penerbit dokumen identitas (misalnya `ESP,USA`), yang mungkin berbeda dari kewarganegaraan. Untuk baris KYB: kode negara dari registri perusahaan.",
            "schema": {
              "type": "string"
            },
            "example": "ESP,USA"
          },
          {
            "name": "document_type",
            "in": "query",
            "required": false,
            "description": "Kode jenis dokumen identitas yang dipisahkan koma yang diverifikasi dalam sesi (hanya baris KYC): `P` (Paspor), `ID` (Kartu Identitas), `DL` (Surat Izin Mengemudi), `RP` (Izin Tinggal), `SSC` (Kartu Jaminan Sosial), `HIC` (Kartu Asuransi Kesehatan), `WP` (Izin Kerja), `TC` (Kartu Pajak), `VISA`, `PSC` (Kartu Layanan Publik), `BC` (Akta Kelahiran), `OTHER`. Perhatikan bahwa kolom respons `document_type` berisi nama tampilan, bukan kodenya.",
            "schema": {
              "type": "string"
            },
            "example": "P,ID"
          },
          {
            "name": "document_name",
            "in": "query",
            "required": false,
            "description": "Nama dokumen persis; beberapa nama dapat diteruskan dipisahkan dengan koma, tetapi nilainya hanya dipisahkan dengan koma jika berisi lebih dari satu pemisah ` - ` (nama tunggal dengan koma di dalamnya dicocokkan secara utuh). Nama sesuai dengan yang dikenali oleh verifikasi dokumen (sisi depan atau belakang), misalnya `Spain - Id Card (2021)`. Baris KYC saja.",
            "schema": {
              "type": "string"
            },
            "example": "Spain - Id Card (2021)"
          },
          {
            "name": "region",
            "in": "query",
            "required": false,
            "description": "Nilai wilayah/negara bagian dokumen yang dipisahkan koma (untuk dokumen yang diterbitkan per wilayah, seperti surat izin mengemudi AS). Hanya baris KYC.",
            "schema": {
              "type": "string"
            },
            "example": "CA,TX"
          },
          {
            "name": "didit_internal_id",
            "in": "query",
            "required": false,
            "description": "Filter berdasarkan pengidentifikasi pengguna internal Didit (kolom respons `didit_internal_id`) untuk mencantumkan semua sesi dari satu pengguna terverifikasi. Harus berupa UUID yang valid; nilai yang salah format mengembalikan `400`. Hanya baris KYC.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "d9e78474-6c8d-4f2a-bb90-6f5c2f3a1147"
          },
          {
            "name": "session_type",
            "in": "query",
            "required": false,
            "description": "Saluran pembuatan sesi yang dipisahkan dengan koma: `API`, `HOSTED`, `MIGRATED`. Nilai khusus `ALL` (atau tidak menyertakan parameter) menonaktifkan filter. Hanya baris KYC.",
            "schema": {
              "type": "string"
            },
            "example": "HOSTED"
          },
          {
            "name": "api_service",
            "in": "query",
            "required": false,
            "description": "Filter sesi API mandiri berdasarkan layanan. Nilai yang tidak valid mengembalikan `400`. Hanya baris KYC.",
            "schema": {
              "type": "string",
              "enum": [
                "ID_VERIFICATION",
                "FACE_MATCH",
                "AGE_ESTIMATION",
                "FACE_SEARCH",
                "POA",
                "AML",
                "KYB_REGISTRY",
                "PASSIVE_LIVENESS",
                "DATABASE_VALIDATION",
                "PHONE_VERIFICATION",
                "EMAIL_VERIFICATION"
              ]
            },
            "example": "AML"
          },
          {
            "name": "screened_full_name",
            "in": "query",
            "required": false,
            "description": "Pencarian nama tidak peka aksen di dalam data yang diskrining pada Skrining AML dan Validasi Database. Jika digabungkan dengan `api_service=AML` atau `api_service=DATABASE_VALIDATION`, pencarian dibatasi pada data yang diskrining fitur tersebut. Hanya baris KYC.",
            "schema": {
              "type": "string"
            },
            "example": "Jane Doe"
          },
          {
            "name": "warning",
            "in": "query",
            "required": false,
            "description": "Kode risiko peringatan yang dipisahkan dengan koma; mengembalikan sesi yang memicu salah satu di antaranya (misalnya `POSSIBLE_FRAUD`). Kode risiko dicantumkan per fitur dalam [dokumentasi peringatan](/id/integration/webhooks). Berlaku untuk baris KYC dan, dengan kode peringatan bisnis, untuk baris KYB.",
            "schema": {
              "type": "string"
            },
            "example": "POSSIBLE_FRAUD"
          },
          {
            "name": "status_initialized_as_in_review",
            "in": "query",
            "required": false,
            "description": "Jika `true`, hanya sesi yang keputusannya awalnya berstatus `In Review` (berguna untuk mengaudit volume peninjauan manual). Baris KYC saja.",
            "schema": {
              "type": "boolean"
            },
            "example": true
          },
          {
            "name": "is_kyc_to_be_reviewed",
            "in": "query",
            "required": false,
            "description": "`true` mengembalikan sesi yang verifikasi dokumennya ditandai untuk peninjauan manual; `false` mengembalikan sesi dengan verifikasi dokumen yang secara eksplisit tidak ditandai. Jangan sertakan untuk menonaktifkan. Hanya baris KYC.",
            "schema": {
              "type": "boolean"
            },
            "example": true
          },
          {
            "name": "euuid",
            "in": "query",
            "required": false,
            "description": "Filter berdasarkan euuid pengguna akhir (UUID yang ditetapkan untuk pengguna yang melakukan verifikasi, digunakan oleh deep link Console). Harus berupa UUID yang valid; nilai yang salah format mengembalikan kesalahan kolom 400. Hanya baris KYC.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "0f8fad5b-d9cb-469f-a165-70867728950e"
          },
          {
            "name": "organization_name",
            "in": "query",
            "required": false,
            "description": "Nama organisasi yang dipisahkan dengan koma. Berorientasi konsol; dengan kunci API (sudah dibatasi pada satu aplikasi), ini hanya cocok dengan nama organisasi Anda sendiri.",
            "schema": {
              "type": "string"
            },
            "example": "Acme Inc"
          }
        ],
        "responses": {
          "200": {
            "description": "Daftar sesi terpaginasi. Item `results` berupa baris KYC, baris KYB, atau keduanya tergantung pada `session_kind`; bedakan dengan kolom `session_kind` di setiap baris.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "count",
                    "next",
                    "previous",
                    "results"
                  ],
                  "properties": {
                    "count": {
                      "type": "integer",
                      "description": "Jumlah sesi yang cocok dengan filter: tepat hingga 100 dan dibatasi maksimal 100 setelahnya, sehingga jangan gunakan sebagai total keseluruhan. Gunakan `next` untuk mengetahui apakah halaman berikutnya masih ada. Untuk `session_kind=all`, ini adalah jumlah kedua jenis, masing-masing dibatasi maksimal 100.",
                      "example": 2
                    },
                    "next": {
                      "type": "string",
                      "format": "uri",
                      "nullable": true,
                      "description": "URL absolut halaman berikutnya, atau `null` di halaman terakhir.",
                      "example": "https://verification.didit.me/v3/sessions/?limit=20&offset=20"
                    },
                    "previous": {
                      "type": "string",
                      "format": "uri",
                      "nullable": true,
                      "description": "URL absolut halaman sebelumnya, atau `null` di halaman pertama.",
                      "example": null
                    },
                    "results": {
                      "type": "array",
                      "description": "Baris sesi, terbaru terlebih dahulu. Dengan `session_kind=all`, baris KYC muncul lebih dulu, kemudian baris KYB.",
                      "items": {
                        "oneOf": [
                          {
                            "$ref": "#/components/schemas/UserSessionListItem"
                          },
                          {
                            "$ref": "#/components/schemas/BusinessSessionListItem"
                          }
                        ],
                        "discriminator": {
                          "propertyName": "session_kind",
                          "mapping": {
                            "user": "#/components/schemas/UserSessionListItem",
                            "business": "#/components/schemas/BusinessSessionListItem"
                          }
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "KYC sessions (default)": {
                    "summary": "session_kind=user - satu sesi selesai dan satu belum dimulai",
                    "value": {
                      "count": 2,
                      "next": null,
                      "previous": null,
                      "results": [
                        {
                          "session_id": "5b3720ed-d429-42ef-b67f-37ea805f48ee",
                          "session_kind": "user",
                          "session_number": 720,
                          "session_url": "https://verify.didit.me/session/CuXoBYCYVO5Y",
                          "portrait_image": "https://<media-host>/portraits/5b3720ed.jpg?X-Amz-Expires=3600&X-Amz-Signature=...",
                          "document_type": "Passport",
                          "full_name": "Jane Marie Doe",
                          "country": "ESP",
                          "status": "Approved",
                          "vendor_data": "your-user-id-123",
                          "didit_internal_id": "d9e78474-6c8d-4f2a-bb90-6f5c2f3a1147",
                          "created_at": "2026-06-09T12:26:54.328364Z",
                          "features": [
                            {
                              "feature": "ID_VERIFICATION",
                              "status": "Approved"
                            },
                            {
                              "feature": "LIVENESS",
                              "status": "Approved"
                            },
                            {
                              "feature": "FACE_MATCH",
                              "status": "Approved"
                            },
                            {
                              "feature": "AML",
                              "status": "Approved"
                            },
                            {
                              "feature": "IP_ANALYSIS",
                              "status": "Approved"
                            }
                          ],
                          "phone_number": {
                            "number": "+14155552671",
                            "is_verified": true
                          },
                          "email_address": {
                            "email": "jane@example.com",
                            "is_verified": true
                          },
                          "additional_details": {
                            "aml": {
                              "total_hits": 0,
                              "entity_type": "person",
                              "is_adverse_media_fetched": false
                            },
                            "liveness": {
                              "method": "PASSIVE",
                              "score": 0.98
                            },
                            "face_match": {
                              "score": 0.95
                            }
                          }
                        },
                        {
                          "session_id": "038ad62f-5ebd-46c2-afe9-4b2956bf687f",
                          "session_kind": "user",
                          "session_number": 719,
                          "session_url": "https://verify.didit.me/session/7RGKiO6ioGH6",
                          "portrait_image": null,
                          "document_type": null,
                          "full_name": null,
                          "country": null,
                          "status": "Not Started",
                          "vendor_data": "your-user-id-124",
                          "didit_internal_id": "eb4e679d-ca4b-461f-9685-687bac29ebdb",
                          "created_at": "2026-06-09T08:02:23.343053Z",
                          "features": [
                            {
                              "feature": "ID_VERIFICATION",
                              "status": "Not Finished"
                            },
                            {
                              "feature": "LIVENESS",
                              "status": "Not Finished"
                            },
                            {
                              "feature": "FACE_MATCH",
                              "status": "Not Finished"
                            },
                            {
                              "feature": "AML",
                              "status": "Not Finished"
                            },
                            {
                              "feature": "IP_ANALYSIS",
                              "status": "Not Finished"
                            }
                          ],
                          "phone_number": null,
                          "email_address": null,
                          "additional_details": null
                        }
                      ]
                    }
                  },
                  "Mixed KYC + KYB (session_kind=all)": {
                    "summary": "session_kind=all - baris KYC diikuti oleh baris KYB",
                    "value": {
                      "count": 2,
                      "next": null,
                      "previous": null,
                      "results": [
                        {
                          "session_id": "5b3720ed-d429-42ef-b67f-37ea805f48ee",
                          "session_kind": "user",
                          "session_number": 720,
                          "session_url": "https://verify.didit.me/session/CuXoBYCYVO5Y",
                          "portrait_image": null,
                          "document_type": "Identity Card",
                          "full_name": "Jane Marie Doe",
                          "country": "ESP",
                          "status": "In Review",
                          "vendor_data": "your-user-id-123",
                          "didit_internal_id": "d9e78474-6c8d-4f2a-bb90-6f5c2f3a1147",
                          "created_at": "2026-06-09T12:26:54.328364Z",
                          "features": [
                            {
                              "feature": "ID_VERIFICATION",
                              "status": "In Review"
                            },
                            {
                              "feature": "LIVENESS",
                              "status": "Approved"
                            }
                          ],
                          "phone_number": null,
                          "email_address": null,
                          "additional_details": {
                            "liveness": {
                              "method": "PASSIVE",
                              "score": 0.98
                            }
                          }
                        },
                        {
                          "session_id": "8a1f63c2-1b9e-4f3a-9c41-2f6a1f0b7d52",
                          "session_kind": "business",
                          "session_number": 42,
                          "status": "Approved",
                          "vendor_data": "your-company-id-77",
                          "created_at": "2026-06-08T09:14:02.118450Z",
                          "workflow_id": "9f9b1234-aaaa-bbbb-cccc-1234567890ab",
                          "workflow_type": "kyb",
                          "workflow_label": "Standard KYB",
                          "company_name": "Acme Holdings S.L.",
                          "registration_number": "B12345678",
                          "country": "ES"
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "301": {
            "description": "Alihkan ke URL kanonis berakhiran garis miring. Dikembalikan saat jalur permintaan adalah `/v3/sessions` (tanpa garis miring akhir); header `Location` mengarah ke `/v3/sessions/` dengan query string tetap dipertahankan. Klien GET biasanya mengikutinya secara otomatis."
          },
          "400": {
            "description": "Parameter kueri tidak valid. Body berupa objek yang diberi kunci berdasarkan parameter yang bermasalah.",
            "content": {
              "application/json": {
                "examples": {
                  "Invalid session_kind": {
                    "summary": "session_kind bukan salah satu dari user/business/all",
                    "value": {
                      "session_kind": "Must be \"user\", \"business\", or \"all\"."
                    }
                  },
                  "Invalid date": {
                    "summary": "date_from/date_to salah format",
                    "value": {
                      "date_from": [
                        "Enter a valid date."
                      ]
                    }
                  },
                  "Invalid didit_internal_id": {
                    "summary": "didit_internal_id bukan sebuah UUID",
                    "value": {
                      "didit_internal_id": [
                        "Enter a valid UUID."
                      ]
                    }
                  },
                  "Invalid api_service": {
                    "summary": "api_service tidak ada dalam pilihan yang diizinkan",
                    "value": {
                      "api_service": [
                        "Select a valid choice. FOO is not one of the available choices."
                      ]
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Kunci API tidak ada, salah format, atau dicabut. Kunci yang tidak ada mengembalikan `403`; kunci yang salah, dicabut, atau kedaluwarsa mengembalikan `401`.\n\n**Aplikasi yang dihapus:** selama beberapa menit setelah aplikasi dihapus, permintaan yang dibuat dengan salah satu kunci API-nya dapat merespons `{\"detail\": \"This application was deleted.\", \"code\": \"application_deleted\"}`. Jangan coba lagi: aplikasi dan kunci API-nya sudah tidak ada. Setelah beberapa menit tersebut, kunci akan ditolak seperti kunci tidak valid lainnya.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "example": "You do not have permission to perform this action."
                    },
                    "code": {
                      "type": "string",
                      "description": "Alasan yang dapat dibaca mesin, hanya ada pada beberapa kegagalan. `application_deleted`: kunci API milik aplikasi yang telah dihapus.",
                      "example": "application_deleted"
                    }
                  },
                  "required": [
                    "detail"
                  ]
                },
                "examples": {
                  "Forbidden": {
                    "summary": "x-api-key tidak ada atau tidak valid",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "ApplicationDeleted": {
                    "summary": "Kunci API dari aplikasi yang dihapus",
                    "value": {
                      "detail": "This application was deleted.",
                      "code": "application_deleted"
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -s 'https://verification.didit.me/v3/sessions/?status=Approved,In%20Review&date_from=2026-06-01&limit=20' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nfor item in client.sessions.list():\n    print(item)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nfor await (const item of didit.sessions.list()) {\n  console.log(item);\n}"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\niter := client.Sessions.ListAutoPaging(ctx, didit.SessionsListParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nfor (var item : client.sessions().list()) {\n    System.out.println(item);\n}"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\nforeach ($didit->sessions->list() as $item) {\n    print_r($item);\n}"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.sessions.list.auto_paging_each do |item|\n  puts item.to_h\nend"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.Sessions.ListAsync())\n{\n    Console.WriteLine(JsonSerializer.Serialize(item));\n}"
          }
        ]
      }
    },
    "/v3/session/{sessionId}/share/": {
      "post": {
        "summary": "Buat token berbagi untuk sesi verifikasi yang telah selesai",
        "description": "Buat JWT berumur pendek yang memungkinkan aplikasi Didit tertentu mengimpor sesi yang telah selesai ini. Pasangkan dengan `POST /v3/session/import-shared/`.",
        "operationId": "post_v3_session_share",
        "x-didit-sdk": {
          "resource": "sessions",
          "method": "share",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Sessions"
        ],
        "responses": {
          "200": {
            "description": "Token berbagi telah dicetak.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "share_token": {
                      "type": "string",
                      "description": "JWT bertanda tangan HS256. Teruskan ini secara persis apa adanya sebagai `share_token` ke [`POST /v3/session/import-shared/`](/sessions-api/import-shared-session) pada aplikasi target.",
                      "example": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
                    },
                    "for_application_id": {
                      "type": "string",
                      "format": "uuid",
                      "description": "Menampilkan kembali UUID aplikasi target yang terikat dengan token tersebut.",
                      "example": "a5f3bca2-46e2-411e-90ef-a580900a57ee"
                    },
                    "session_kind": {
                      "type": "string",
                      "enum": [
                        "user",
                        "business"
                      ],
                      "description": "Apakah sesi sumber merupakan sesi Verifikasi Pengguna (KYC) atau Verifikasi Bisnis (KYB)."
                    }
                  }
                },
                "examples": {
                  "User session": {
                    "summary": "Bagikan sesi KYC",
                    "value": {
                      "share_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzZXNzaW9uX2lkIjoiMjBiYjNjM2ItNjE0Ni00MzlmLTg0YTQtYmQzMGQwMGFjNmEyIiwiZnJvbV9hcHBsaWNhdGlvbl9pZCI6ImRiZDIwZTM0LTQyZTktNGYyYy1iYTkxLWNmMDc2MjAxNmY2NCIsImZvcl9hcHBsaWNhdGlvbl9pZCI6ImE1ZjNiY2EyLTQ2ZTItNDExZS05MGVmLWE1ODA5MDBhNTdlZSIsImlhdCI6MTc1MzYzMDY2NiwiZXhwIjoxNzUzNjM0MjY2fQ.JJ9pNE_hqZsOtbR0XYZIWw4JzidjdEl279iUrsIkhGE",
                      "for_application_id": "a5f3bca2-46e2-411e-90ef-a580900a57ee",
                      "session_kind": "user"
                    }
                  },
                  "Business session": {
                    "summary": "Bagikan sesi KYB",
                    "value": {
                      "share_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
                      "for_application_id": "a5f3bca2-46e2-411e-90ef-a580900a57ee",
                      "session_kind": "business"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Kredensial tidak ada atau tidak valid. Tidak seperti sebagian besar endpoint v3, endpoint ini mengautentikasi melalui dekorator izin dan mengembalikan `401` saat tidak ada token/kunci valid yang diberikan.",
            "content": {
              "application/json": {
                "examples": {
                  "Unauthorized": {
                    "summary": "Tidak diotorisasi",
                    "value": {
                      "detail": "Authentication credentials were not provided or are invalid."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Tidak ada sesi dengan `session_id` yang diberikan di aplikasi Anda.",
            "content": {
              "application/json": {
                "examples": {
                  "Not Found": {
                    "summary": "Sesi tidak ditemukan",
                    "value": {
                      "detail": "Not found."
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Kesalahan validasi. Kesalahan pada kolom menggunakan nama kolom sebagai kunci; kesalahan belum selesai muncul di bawah kunci `detail` (sebagai array).",
            "content": {
              "application/json": {
                "examples": {
                  "Wrong status": {
                    "summary": "Sesi sumber belum selesai",
                    "value": {
                      "detail": [
                        "Only finished sessions (\"Approved\", \"Declined\", \"In Review\") can be shared."
                      ]
                    }
                  },
                  "Target missing": {
                    "summary": "Aplikasi target tidak ada",
                    "value": {
                      "for_application_id": [
                        "Target application does not exist."
                      ]
                    }
                  },
                  "Self-share": {
                    "summary": "Target adalah aplikasi pemanggil",
                    "value": {
                      "for_application_id": [
                        "Cannot share a session with the same application."
                      ]
                    }
                  },
                  "TTL bounds": {
                    "summary": "ttl_in_seconds di luar batas",
                    "value": {
                      "ttl_in_seconds": [
                        "Ensure this value is greater than or equal to 60."
                      ]
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Kredensial valid tetapi tidak memiliki izin `write:sessions` untuk aplikasi ini.",
            "content": {
              "application/json": {
                "examples": {
                  "No Permission": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    },
                    "summary": "Tidak Ada Izin"
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "in": "path",
            "name": "sessionId",
            "required": true,
            "description": "UUID sesi verifikasi sumber untuk mencetak token.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "11111111-2222-3333-4444-555555555555"
            }
          }
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "for_application_id"
                ],
                "properties": {
                  "for_application_id": {
                    "type": "string",
                    "format": "uuid",
                    "description": "UUID aplikasi Didit yang akan menukarkan token. Harus ada, tidak boleh dihapus, dan harus berbeda dari aplikasi pemanggil. Temukan di Business Console di bawah **Settings → Application**.",
                    "example": "a5f3bca2-46e2-411e-90ef-a580900a57ee"
                  },
                  "ttl_in_seconds": {
                    "type": "integer",
                    "description": "Masa berlaku token, dalam detik. Minimum `60`, maksimum `86400` (24 jam). Defaultnya `3600` (1 jam).",
                    "minimum": 60,
                    "maximum": 86400,
                    "default": 3600,
                    "example": 3600
                  }
                }
              },
              "example": {
                "for_application_id": "a5f3bca2-46e2-411e-90ef-a580900a57ee",
                "ttl_in_seconds": 7200
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST \\\n  https://verification.didit.me/v3/session/11111111-2222-3333-4444-555555555555/share/ \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"for_application_id\": \"a5f3bca2-46e2-411e-90ef-a580900a57ee\",\n    \"ttl_in_seconds\": 7200\n  }'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.share(\n    \"11111111-2222-3333-4444-555555555555\",\n    for_application_id=\"a5f3bca2-46e2-411e-90ef-a580900a57ee\",\n    ttl_in_seconds=7200,\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.share(\"11111111-2222-3333-4444-555555555555\", {\n  for_application_id: \"a5f3bca2-46e2-411e-90ef-a580900a57ee\",\n  ttl_in_seconds: 7200,\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.Share(ctx, \"11111111-2222-3333-4444-555555555555\", didit.SessionsShareParams{\n\tForApplicationID: \"a5f3bca2-46e2-411e-90ef-a580900a57ee\",\n\tTTLInSeconds:     didit.Int(7200),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.SessionsShareParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().share(\"11111111-2222-3333-4444-555555555555\", SessionsShareParams.builder()\n        .forApplicationId(\"a5f3bca2-46e2-411e-90ef-a580900a57ee\")\n        .ttlInSeconds(7200L)\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->sessions->share('11111111-2222-3333-4444-555555555555', [\n    'for_application_id' => 'a5f3bca2-46e2-411e-90ef-a580900a57ee',\n    'ttl_in_seconds' => 7200,\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.share(\n  \"11111111-2222-3333-4444-555555555555\",\n  for_application_id: \"a5f3bca2-46e2-411e-90ef-a580900a57ee\",\n  ttl_in_seconds: 7200\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.ShareAsync(\"11111111-2222-3333-4444-555555555555\", new SessionsShareParams\n{\n    ForApplicationId = \"a5f3bca2-46e2-411e-90ef-a580900a57ee\",\n    TtlInSeconds = 7200,\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/session/import-shared/": {
      "post": {
        "summary": "Tukarkan token berbagi untuk mengkloning sesi verifikasi ke dalam aplikasi Anda",
        "description": "Tukarkan token berbagi untuk mengkloning sesi KYC atau KYB ke dalam aplikasi pemanggil dengan `session_id` baru. Tidak bersifat idempoten — token hanya dapat ditukarkan sekali per penerima.",
        "operationId": "post_v3_session_import_shared",
        "x-didit-sdk": {
          "resource": "sessions",
          "method": "import_shared",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Sessions"
        ],
        "responses": {
          "201": {
            "description": "Sesi dikloning. Isi respons adalah payload keputusan V3 untuk kedua jenis, dibedakan berdasarkan `session_kind`: `\"user\"` (KYC) dengan blok fitur berbasis daftar seperti `id_verifications`, `liveness_checks`, `aml_screenings`; `\"business\"` (KYB) dengan blok seperti `registry_checks` dan `key_people_checks`. Keduanya menyertakan `shared_from_session` — `session_id` dari sesi asli di aplikasi sumber. Dengan `trust_review: false`, `status` sesi yang dikloning dipaksa menjadi `In Review`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SessionDecision"
                },
                "examples": {
                  "User session imported": {
                    "summary": "Sesi KYC yang dikloning (dipotong — payload keputusan V3 lengkap pada kenyataannya)",
                    "value": {
                      "session_id": "11111111-2222-3333-4444-555555555555",
                      "session_kind": "user",
                      "shared_from_session": "99999999-8888-7777-6666-555555555555",
                      "session_number": 43762,
                      "session_url": null,
                      "status": "In Review",
                      "workflow_id": "9f9b1234-aaaa-bbbb-cccc-1234567890ab",
                      "vendor_data": "user-1",
                      "created_at": "2026-05-17T08:42:11Z",
                      "expires_at": "2026-05-24T08:42:11Z"
                    }
                  },
                  "Business session imported": {
                    "summary": "Sesi KYB yang dikloning (dipotong — payload keputusan KYB V3 lengkap pada kenyataannya)",
                    "value": {
                      "session_id": "22222222-3333-4444-5555-666666666666",
                      "session_kind": "business",
                      "shared_from_session": "88888888-7777-6666-5555-444444444444",
                      "session_number": 982,
                      "session_url": null,
                      "status": "Approved",
                      "workflow_id": "9f9b1234-aaaa-bbbb-cccc-1234567890ab",
                      "vendor_data": "company-1"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Kesalahan validasi (token tidak valid, kedaluwarsa, target salah, atau mereferensikan sesi yang sudah tidak ada).",
            "content": {
              "application/json": {
                "examples": {
                  "Invalid Share Token": {
                    "summary": "JWT tidak valid",
                    "value": {
                      "share_token": [
                        "Invalid share token."
                      ]
                    }
                  },
                  "Expired Share Token": {
                    "summary": "Token melewati `exp`",
                    "value": {
                      "share_token": [
                        "Share token has expired."
                      ]
                    }
                  },
                  "Wrong audience": {
                    "summary": "Token tidak terikat ke aplikasi ini",
                    "value": {
                      "share_token": [
                        "This token is not valid for this application."
                      ]
                    }
                  },
                  "Original missing": {
                    "summary": "Sesi sumber telah dihapus",
                    "value": {
                      "share_token": [
                        "Original session does not exist."
                      ]
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Kunci API tidak ada (kunci yang salah, dicabut, atau kedaluwarsa mendapatkan `401`), atau sesi sumber ini telah diimpor ke dalam aplikasi pemanggil (satu penukaran per penerima).",
            "content": {
              "application/json": {
                "examples": {
                  "Forbidden": {
                    "summary": "Dilarang",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Already imported": {
                    "summary": "Sumber sudah diimpor satu kali",
                    "value": {
                      "detail": "This session has already been shared with your application."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "`workflow_id` bukan milik aplikasi yang memanggil.",
            "content": {
              "application/json": {
                "examples": {
                  "Workflow not found": {
                    "summary": "Alur kerja tidak diketahui",
                    "value": {
                      "detail": "Workflow does not exist for this application."
                    }
                  }
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "share_token",
                  "trust_review",
                  "workflow_id"
                ],
                "properties": {
                  "share_token": {
                    "type": "string",
                    "description": "Token berbagi JWT yang diterbitkan oleh [`POST /v3/session/{sessionId}/share/`](/sessions-api/share-session).",
                    "example": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
                  },
                  "trust_review": {
                    "type": "boolean",
                    "description": "Jika `true`, sesi hasil kloning mempertahankan `status` akhir sumbernya. Jika `false`, statusnya dipaksa menjadi `In Review`.",
                    "example": false
                  },
                  "workflow_id": {
                    "type": "string",
                    "format": "uuid",
                    "description": "UUID alur kerja di aplikasi pemanggil. ID lintas aplikasi ditolak dengan `404`.",
                    "example": "9f9b1234-aaaa-bbbb-cccc-1234567890ab"
                  },
                  "vendor_data": {
                    "type": "string",
                    "nullable": true,
                    "description": "Penimpaan opsional untuk `vendor_data` dari sesi yang dikloning.",
                    "example": "user-1"
                  }
                }
              },
              "example": {
                "share_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
                "trust_review": false,
                "workflow_id": "9f9b1234-aaaa-bbbb-cccc-1234567890ab",
                "vendor_data": "user-1"
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST \\\n  https://verification.didit.me/v3/session/import-shared/ \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"share_token\": \"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...\",\n    \"trust_review\": false,\n    \"workflow_id\": \"9f9b1234-aaaa-bbbb-cccc-1234567890ab\",\n    \"vendor_data\": \"user-1\"\n  }'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.import_shared(\n    share_token=\"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...\",\n    trust_review=False,\n    workflow_id=\"9f9b1234-aaaa-bbbb-cccc-1234567890ab\",\n    vendor_data=\"user-1\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.importShared({\n  share_token: \"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...\",\n  trust_review: false,\n  workflow_id: \"9f9b1234-aaaa-bbbb-cccc-1234567890ab\",\n  vendor_data: \"user-1\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.ImportShared(ctx, didit.SessionsImportSharedParams{\n\tShareToken:  \"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...\",\n\tTrustReview: false,\n\tWorkflowID:  \"9f9b1234-aaaa-bbbb-cccc-1234567890ab\",\n\tVendorData:  didit.String(\"user-1\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.SessionsImportSharedParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().importShared(SessionsImportSharedParams.builder()\n        .shareToken(\"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...\")\n        .trustReview(false)\n        .workflowId(\"9f9b1234-aaaa-bbbb-cccc-1234567890ab\")\n        .vendorData(\"user-1\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->sessions->importShared([\n    'share_token' => 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...',\n    'trust_review' => false,\n    'workflow_id' => '9f9b1234-aaaa-bbbb-cccc-1234567890ab',\n    'vendor_data' => 'user-1',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.import_shared(\n  share_token: \"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...\",\n  trust_review: false,\n  workflow_id: \"9f9b1234-aaaa-bbbb-cccc-1234567890ab\",\n  vendor_data: \"user-1\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.ImportSharedAsync(new SessionsImportSharedParams\n{\n    ShareToken = \"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...\",\n    TrustReview = false,\n    WorkflowId = \"9f9b1234-aaaa-bbbb-cccc-1234567890ab\",\n    VendorData = \"user-1\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/kyb/search/": {
      "post": {
        "summary": "Pencarian perusahaan registri KYB (mandiri)",
        "operationId": "post_v3_kyb_search",
        "x-didit-sdk": {
          "resource": "kyb",
          "method": "search",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Standalone APIs"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [],
        "description": "Cari registri perusahaan resmi untuk kandidat perusahaan berdasarkan nama dan/atau nomor registrasi. Ini adalah langkah 1 dari alur registri dua langkah: **pencarian** mengembalikan kandidat ringkas, lalu `POST /v3/kyb/select/` mengambil profil lengkap dari satu kandidat.\n\n**Penagihan pencarian.** Pencarian yang berhasil menggunakan sumber data perusahaan berbayar dikenakan biaya USD 0.50 per permintaan, terlepas dari jumlah kandidat. Hasil kosong, kegagalan, dan hasil yang hanya disajikan oleh sumber lain tidak dikenakan biaya. Harga yang berlaku dicadangkan sebelum pencarian; saldo yang tidak mencukupi mengembalikan 403 dengan kode `insufficient_credits`. Tarif kontrak berlaku jika disepakati, dan tarif pencarian kontrak yang belum dikonfigurasi mengembalikan 403. Pencarian sandbox gratis. Mengulangi pencarian yang berhasil dapat dikenai biaya lain; pengiriman callback tidak menambah biaya. Pengambilan profil ditagihkan secara terpisah. Biaya pencarian ini juga berlaku untuk v2. Kandidat selalu dikembalikan dengan `fetch_status: \"pending\"`: data lengkap perusahaan hanya diambil (dan ditagih) saat pemilihan (select).\n\n**`kyb_response_id` bersifat efemeral.** Ini adalah handle per pencarian, bukan id perusahaan yang stabil. Lakukan select segera setelah mencari dan cari ulang untuk mendapatkan handle baru daripada menyimpannya.\n\n**`tier` memilih rantai penyedia.** `tier` menentukan tingkat registri tempat pencarian berjalan: `basic` (default, rantai Lite), `shareholders`, atau `ubo`. Pencarian menggunakan rantai penyedia yang melayani tingkat tersebut, dan ini tidak selalu merupakan rantai yang sama yang dibaca oleh pencarian Lite, jadi pencarian Lite yang kosong bukanlah bukti bahwa registri tidak memuat perusahaan tersebut — cari lagi pada tingkat yang Anda butuhkan. Negara yang tidak menawarkan tingkat yang Anda tentukan akan dicari pada tingkat tertinggi yang ditawarkannya hingga tingkat tersebut. Ambil kandidat dari endpoint yang menyediakan tingkat tersebut: `POST /v3/kyb/select/` (Lite), `POST /v3/kyb/shareholders/`, atau `POST /v3/kyb/ubo/`.\n\n**Autentikasi.** `POST /v3/kyb/search/` (dan `/v2/`) memerlukan kunci API aplikasi Anda di header `x-api-key`. `POST /v1/kyb/search/` yang di-hosting adalah rute terautentikasi sesi yang dipanggil oleh alur verifikasi yang di-hosting: endpoint ini merespons `403` untuk kunci API dan tidak menerima `tier` — konfigurasi registri KYB pada alur kerja akan memilih rantainya.\n\n**Dua mode.**\n- *Sinkron (default):* API melakukan polling pada registri hingga pencarian selesai dan mengembalikan daftar kandidat akhir (`search_resolved: true`).\n- *Asinkron:* kirimkan `webhook_url` dan API akan langsung merespons — biasanya dengan `search_status: \"pending\"` dan daftar kandidat kosong — lalu mengirimkan POST callback `kyb.registry_search.resolved` ke URL Anda saat registri selesai. Body callback adalah `{\"event_id\", \"event_type\": \"kyb.registry_search.resolved\", \"request_id\", \"vendor_data\", \"metadata\", \"search_status\", \"search_resolved\", \"kyb_registry\", \"timestamp\", \"created_at\"}` — perhatikan bahwa `timestamp` dan `created_at` dalam callback adalah bilangan bulat epoch, tidak seperti ISO `created_at` pada endpoint ini — dan dikirim **tanpa tanda tangan** (header `X-Didit-Unsigned-Callback: true`, tanpa `X-Signature`).\n\n**Kode negara.** ISO 3166-1 alpha-2 (`GB`, `DE`), ditambah kode subdivisi `XX-YY` untuk registri regional — misalnya `US-CA` untuk California.\n\n**Sandbox.** Kunci dari aplikasi sandbox mengembalikan satu kandidat statis tanpa menghubungi registri apa pun.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "country_code"
                ],
                "properties": {
                  "country_code": {
                    "type": "string",
                    "maxLength": 10,
                    "description": "Kode ISO 3166-1 alpha-2 untuk negara yang registri perusahaannya akan dicari. Misalnya, `GB`. Jika registri perusahaan beroperasi di tingkat negara bagian atau provinsi, tambahkan kode subdivisi ISO 3166-2 sebagai `XX-YY`: `US-CA` mencari di registri California. Pencarian untuk Amerika Serikat selalu memerlukan subdivisi — kode `US` saja akan ditolak. Tidak peka huruf besar/kecil; dinormalisasi ke huruf besar.",
                    "example": "GB"
                  },
                  "name": {
                    "type": "string",
                    "maxLength": 255,
                    "description": "Nama perusahaan yang akan dicari. Salah satu dari `name` atau `registration_number` diperlukan.",
                    "example": "Tesco"
                  },
                  "registration_number": {
                    "type": "string",
                    "maxLength": 100,
                    "description": "Nomor registrasi registri yang dicari. Salah satu dari `name` atau `registration_number` wajib diisi."
                  },
                  "tier": {
                    "type": "string",
                    "enum": [
                      "basic",
                      "shareholders",
                      "ubo"
                    ],
                    "default": "basic",
                    "description": "Tingkat registri tempat rantai penyedia pencarian ini dijalankan. `basic` (default) mencari rantai Lite negara tersebut; `shareholders` dan `ubo` mencari rantai kepemilikan tingkat tersebut, yang dapat menjadi sumber berbeda, sehingga pencarian Lite yang kosong tidak membuktikan bahwa registri tidak memiliki perusahaan tersebut. Negara yang tidak menawarkan tingkat yang disebutkan akan dicari pada tingkat tertinggi yang ditawarkannya hingga tingkat tersebut. Ambil kandidat dari endpoint yang menjual tingkat yang Anda cari: `POST /v3/kyb/select/` (Lite), `POST /v3/kyb/shareholders/` atau `POST /v3/kyb/ubo/`.",
                    "example": "basic"
                  },
                  "search_type": {
                    "type": "string",
                    "enum": [
                      "contains"
                    ],
                    "default": "contains",
                    "description": "Strategi pencocokan nama yang diterapkan oleh pencarian registri. `contains` adalah satu-satunya nilai yang diterima: tidak ada sumber registri di balik pencarian yang menawarkan mode awalan atau fuzzy, sehingga `start_with` dan `fuzzy` ditolak dengan `400` (`not a valid choice`)."
                  },
                  "vendor_data": {
                    "type": "string",
                    "description": "Pengenal Anda untuk pencarian ini; dikembalikan dan disertakan dalam callback webhook."
                  },
                  "metadata": {
                    "type": "object",
                    "nullable": true,
                    "description": "JSON bentuk bebas; dikembalikan dalam respons dan disertakan dalam callback webhook."
                  },
                  "webhook_url": {
                    "type": "string",
                    "format": "uri",
                    "maxLength": 500,
                    "description": "Mengalihkan pencarian ke mode asinkron: API segera memberikan respons dan mengirimkan POST callback `kyb.registry_search.resolved` yang tidak ditandatangani ke URL ini saat daftar kandidat sudah siap."
                  }
                }
              },
              "example": {
                "country_code": "GB",
                "name": "Tesco",
                "search_type": "contains",
                "vendor_data": "company-1234"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST https://verification.didit.me/v3/kyb/search/ \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"country_code\": \"GB\",\n    \"name\": \"Tesco\",\n    \"search_type\": \"contains\",\n    \"vendor_data\": \"company-1234\"\n  }'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.kyb.search(\n    country_code=\"GB\",\n    name=\"Tesco\",\n    search_type=\"contains\",\n    vendor_data=\"company-1234\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.kyb.search({\n  country_code: \"GB\",\n  name: \"Tesco\",\n  search_type: \"contains\",\n  vendor_data: \"company-1234\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.KYB.Search(ctx, didit.KYBSearchParams{\n\tCountryCode: \"GB\",\n\tName:        didit.String(\"Tesco\"),\n\tSearchType:  didit.Some(didit.KYBSearchParamsSearchType(\"contains\")),\n\tVendorData:  didit.String(\"company-1234\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.KybSearchParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.kyb().search(KybSearchParams.builder()\n        .countryCode(\"GB\")\n        .name(\"Tesco\")\n        .searchType(KybSearchParams.SearchType.of(\"contains\"))\n        .vendorData(\"company-1234\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->kyb->search([\n    'country_code' => 'GB',\n    'name' => 'Tesco',\n    'search_type' => 'contains',\n    'vendor_data' => 'company-1234',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.kyb.search(\n  country_code: \"GB\",\n  name: \"Tesco\",\n  search_type: \"contains\",\n  vendor_data: \"company-1234\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Kyb.SearchAsync(new KybSearchParams\n{\n    CountryCode = \"GB\",\n    Name = \"Tesco\",\n    SearchType = new KybSearchParamsSearchType(\"contains\"),\n    VendorData = \"company-1234\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "Pencarian diterima. Mode sinkron mengembalikan daftar kandidat hasil akhir; mode webhook mengembalikan respons segera (sering kali `search_status: \"pending\"`) dan mengirimkan daftar akhir melalui callback `kyb.registry_search.resolved`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "request_id": {
                      "type": "string",
                      "format": "uuid",
                      "description": "Dengan `webhook_url`: id permintaan pencarian yang disimpan, ditampilkan kembali sebagai `request_id` dalam callback `kyb.registry_search.resolved`. Tanpa `webhook_url`: UUID korelasi sementara (pencarian tidak disimpan)."
                    },
                    "kyb_registry": {
                      "$ref": "#/components/schemas/KYBRegistrySearchResults"
                    },
                    "vendor_data": {
                      "type": "string",
                      "nullable": true,
                      "description": "Menampilkan kembali `vendor_data` yang Anda kirimkan."
                    },
                    "metadata": {
                      "type": "object",
                      "nullable": true,
                      "description": "Salinan `metadata` yang Anda kirimkan."
                    },
                    "created_at": {
                      "type": "string",
                      "format": "date-time"
                    }
                  }
                },
                "examples": {
                  "Resolved search": {
                    "summary": "Mode sinkron — daftar kandidat akhir",
                    "value": {
                      "request_id": "0c7e9a40-3a13-4f7e-8a44-9d2e2f1c5b6a",
                      "kyb_registry": {
                        "companies": [
                          {
                            "kyb_response_id": "69aeeb95febb0f1704042259",
                            "name": "Tesco PLC",
                            "registration_number": "00445790",
                            "status": "active",
                            "type": "Public Limited Company",
                            "risk_level": null,
                            "fetch_status": "pending"
                          },
                          {
                            "kyb_response_id": "69aeeb95febb0f170404225a",
                            "name": "E-TESCO LTD",
                            "registration_number": "15168476",
                            "status": "active",
                            "type": "Private Limited Company",
                            "risk_level": null,
                            "fetch_status": "pending"
                          }
                        ],
                        "pagination": {
                          "total": 2,
                          "page": 1,
                          "per_page": 25
                        },
                        "search_status": "resolved",
                        "search_resolved": true
                      },
                      "vendor_data": "company-1234",
                      "metadata": null,
                      "created_at": "2026-06-11T10:40:00.000000+00:00"
                    }
                  },
                  "Pending search (webhook mode)": {
                    "summary": "`webhook_url` disediakan — kandidat masuk melalui callback kyb.registry_search.resolved",
                    "value": {
                      "request_id": "5f2d8c1b-7e4a-4b9c-9f0d-3a6e8c2b1d4f",
                      "kyb_registry": {
                        "companies": [],
                        "pagination": {
                          "total": 0,
                          "page": 1,
                          "per_page": 25
                        },
                        "search_status": "pending",
                        "search_resolved": false
                      },
                      "vendor_data": "company-1234",
                      "metadata": {
                        "source": "onboarding"
                      },
                      "created_at": "2026-06-11T10:41:00.000000+00:00"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Kesalahan validasi. Masalah tingkat kolom menggunakan format standar DRF; aturan nama/nomor registrasi dilaporkan di bawah `non_field_errors`. Negara yang tidak dicakup oleh registri akan menghasilkan respons `400` dengan `code: kyb_registry_country_unsupported`.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing search criteria": {
                    "summary": "Baik `name` maupun `registration_number` tidak diberikan",
                    "value": {
                      "non_field_errors": [
                        "Either 'name' or 'registration_number' is required."
                      ]
                    }
                  },
                  "Invalid country_code": {
                    "summary": "Harus berupa `XX` (alpha-2) atau subdivisi `XX-YY`",
                    "value": {
                      "country_code": [
                        "country_code must be a 2-letter ISO code."
                      ]
                    }
                  },
                  "Invalid search_type": {
                    "summary": "Hanya `contains` yang diterima",
                    "value": {
                      "search_type": [
                        "\"start_with\" is not a valid choice."
                      ]
                    }
                  },
                  "Invalid webhook_url": {
                    "summary": "`webhook_url` harus berupa URL yang valid",
                    "value": {
                      "webhook_url": [
                        "Enter a valid URL."
                      ]
                    }
                  },
                  "Country not covered": {
                    "summary": "Tidak ada registri perusahaan yang mencakup negara tersebut",
                    "value": {
                      "detail": "Company registry search is not available for this country. Enter the company details manually to continue.",
                      "code": "kyb_registry_country_unsupported"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Izin ditolak. Dikembalikan ketika header `x-api-key` tidak ada; kunci yang salah, dicabut, atau kedaluwarsa mengembalikan `401`. Kunci yang tidak ada mengembalikan `403` dengan `{\"detail\": ...}`; kunci yang salah, dicabut, atau kedaluwarsa mengembalikan `401`. Juga dikembalikan sebelum pencarian ketika biaya pencarian yang berlaku tidak dapat ditanggung (`code: \"insufficient_credits\"`), atau ketika tarif pencarian kontrak tidak ada.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing or invalid API key": {
                    "summary": "Tidak ada header `x-api-key`, atau kuncinya tidak valid/dicabut",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Batas laju terlampaui, atau kuota pencarian telah habis. Endpoint POST/PATCH/DELETE berbagi anggaran 300 permintaan penulisan per menit per kunci API (pembuatan transaksi dan ingesti event memiliki anggaran terpisah sebesar 600), dengan header `X-RateLimit-*` dan `Retry-After`. Secara terpisah, pencarian registri berbayar dibatasi hingga 600 per aplikasi per jam: melebihi itu, responsnya adalah `429` dengan `code: kyb_registry_search_limit_reached`, dan pencarian yang hanya dilayani oleh sumber gratis tetap berfungsi. Tunggu dan cari lagi nanti.",
            "content": {
              "application/json": {
                "examples": {
                  "Write rate limit exceeded": {
                    "summary": "Lebih dari 300 permintaan tulis pada menit ini",
                    "value": {
                      "detail": "Write request rate limit exceeded. You can make up to 300 requests per minute."
                    }
                  },
                  "Search allowance spent": {
                    "summary": "Lebih dari 600 pencarian berbayar dalam satu jam terakhir",
                    "value": {
                      "detail": "The maximum number of company registry searches for this session has been reached. Enter the company details manually to continue.",
                      "code": "kyb_registry_search_limit_reached"
                    }
                  }
                },
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "502": {
            "description": "Penyedia registri KYB untuk sementara tidak tersedia - respons 5xx, batas waktu habis, atau kegagalan koneksi dari registri hulu. Pencarian tidak ditagih. Coba lagi nanti, atau, dalam alur verifikasi yang di-hosting Didit, pengguna secara otomatis ditawari entri perusahaan manual alih-alih kesalahan yang hanya meminta coba lagi.",
            "content": {
              "application/json": {
                "examples": {
                  "Registry provider outage": {
                    "summary": "Penyedia registri tidak merespons pencarian",
                    "value": {
                      "detail": "The KYB registry provider is temporarily unavailable. Please try again shortly.",
                      "code": "kyb_registry_provider_unavailable"
                    }
                  }
                },
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v3/kyb/select/": {
      "post": {
        "summary": "Pemilihan perusahaan registri KYB — tingkat Lite (mandiri)",
        "operationId": "post_v3_kyb_select",
        "x-didit-sdk": {
          "resource": "kyb",
          "method": "select",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Standalone APIs"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [],
        "description": "Ambil profil registri **Lite** dari satu kandidat yang dikembalikan oleh `POST /v3/kyb/search/` — detail perusahaan, alamat terdaftar, pengidentifikasi, status, aktivitas, dan para pengurus, ditambah payload mentah registri. Pemegang saham dan pemilik manfaat akhir (UBO) dijual melalui `POST /v3/kyb/shareholders/` dan `POST /v3/kyb/ubo/`.\n\n**Penyandingan dengan pencarian.** Teruskan `kyb_response_id` kandidat persis seperti yang dikembalikan oleh pencarian pada aplikasi yang sama. Handle ini bersifat sementara dan hanya berlaku untuk pencarian tersebut — lakukan pemilihan segera, dan cari ulang untuk mendapatkan handle baru daripada menyimpannya.\n\n**Penagihan.** Setiap pemilihan ditagih sesuai harga Lite negara tersebut (biaya pencarian apa pun terpisah); lihat [Harga registri KYB](/id/getting-started/kyb-registry-pricing). Saldo diperiksa sebelum panggilan registri apa pun (`403` jika tidak mencukupi) dan biaya dicatat pada sesi bisnis yang dibuat.\n\n**Persistensi wajib dilakukan.** Setiap pemilihan membuat sesi bisnis (id-nya adalah `request_id`) sehingga penagihan dan pengambilan data dapat dilacak; sesi ini muncul di konsol. `save_api_request` diterima demi keselarasan struktur tetapi harus bernilai `true` (default) — mengirimkan `false` akan mengembalikan `400`.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/KYBRegistryCandidateRequest"
              },
              "example": {
                "kyb_response_id": "69aeeb95febb0f1704042259",
                "vendor_data": "company-1234"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST https://verification.didit.me/v3/kyb/select/ \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"kyb_response_id\": \"69aeeb95febb0f1704042259\",\n    \"vendor_data\": \"company-1234\"\n  }'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.kyb.select(\n    kyb_response_id=\"69aeeb95febb0f1704042259\",\n    vendor_data=\"company-1234\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.kyb.select({\n  kyb_response_id: \"69aeeb95febb0f1704042259\",\n  vendor_data: \"company-1234\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.KYB.Select(ctx, didit.KYBRegistryCandidateRequest{\n\tKYBResponseID: \"69aeeb95febb0f1704042259\",\n\tVendorData:    didit.String(\"company-1234\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.KYBRegistryCandidateRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.kyb().select(KYBRegistryCandidateRequest.builder()\n        .kybResponseId(\"69aeeb95febb0f1704042259\")\n        .vendorData(\"company-1234\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->kyb->select([\n    'kyb_response_id' => '69aeeb95febb0f1704042259',\n    'vendor_data' => 'company-1234',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.kyb.select(\n  kyb_response_id: \"69aeeb95febb0f1704042259\",\n  vendor_data: \"company-1234\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Kyb.SelectAsync(new KYBRegistryCandidateRequest\n{\n    KybResponseId = \"69aeeb95febb0f1704042259\",\n    VendorData = \"company-1234\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "Perusahaan diambil dan ditagih. `kyb_registry` memuat profil lengkap; periksa `data_resolved` — jika `false`, registri masih memproses, dan rekaman yang disimpan akan dilengkapi secara otomatis setelah registri menyelesaikan pemrosesan.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "request_id": {
                      "type": "string",
                      "format": "uuid",
                      "description": "ID sesi bisnis yang dibuat untuk pengambilan ini. Catatan yang disimpan (terlihat di konsol) terus diperbarui jika registri berhasil menyelesaikan pencarian setelah respons."
                    },
                    "registry_tier_requested": {
                      "type": "string",
                      "enum": [
                        "basic",
                        "shareholders",
                        "ubo"
                      ],
                      "description": "Tingkat yang dijual endpoint ini: `basic` (Lite) untuk opsi tertentu, `shareholders`, `ubo`."
                    },
                    "registry_tier_delivered": {
                      "type": "string",
                      "enum": [
                        "basic",
                        "shareholders",
                        "ubo"
                      ],
                      "description": "Tingkat yang benar-benar dikirimkan dan ditagihkan. Lebih rendah dari yang diminta jika registri negara tersebut tidak menyimpan data kepemilikan, atau registri tidak memiliki catatan kepemilikan untuk perusahaan ini."
                    },
                    "kyb_registry": {
                      "type": "object",
                      "description": "Profil perusahaan registri lengkap.",
                      "properties": {
                        "uuid": {
                          "type": "string",
                          "format": "uuid",
                          "description": "ID Didit untuk catatan perusahaan ini."
                        },
                        "node_id": {
                          "type": "string",
                          "example": "feature_kyb_registry"
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "Not Finished",
                            "Approved",
                            "Declined",
                            "In Review"
                          ],
                          "description": "Penilaian Didit atas pemeriksaan registri (misalnya `In Review` ketika perusahaan tidak aktif di registri atau data kepemilikan tidak dapat diturunkan)."
                        },
                        "registry_status": {
                          "type": "string",
                          "nullable": true,
                          "enum": [
                            "active",
                            "dissolved",
                            "deregistered",
                            "see full details",
                            "authorised",
                            "appointed representative",
                            "unauthorised",
                            "inactive",
                            "no longer authorised",
                            "closed",
                            "struck off"
                          ],
                          "description": "Status perusahaan yang dinormalisasi sebagaimana dilaporkan oleh registri."
                        },
                        "data_resolved": {
                          "type": "boolean",
                          "description": "`true` setelah registri mengembalikan profil lengkap. `false` jika registri masih memproses setelah polling — data yang disimpan akan selesai secara otomatis setelah registri selesai memproses."
                        },
                        "company_name": {
                          "type": "string",
                          "example": "Tesco PLC"
                        },
                        "registration_number": {
                          "type": "string",
                          "nullable": true,
                          "example": "00445790"
                        },
                        "country_code": {
                          "type": "string",
                          "description": "ISO 3166-1 alpha-2.",
                          "example": "GB"
                        },
                        "region": {
                          "type": "string",
                          "nullable": true,
                          "description": "Kode subdivisi jika registri bersifat regional (misalnya `CA` untuk `US-CA`); kosong jika tidak."
                        },
                        "company_type": {
                          "type": "string",
                          "nullable": true,
                          "example": "Public Limited Company"
                        },
                        "incorporation_date": {
                          "type": "string",
                          "format": "date",
                          "nullable": true,
                          "example": "1947-11-27"
                        },
                        "registered_address": {
                          "type": "string",
                          "nullable": true,
                          "example": "Tesco House, Shire Park, Kestrel Way, Welwyn Garden City, United Kingdom, AL7 1GA"
                        },
                        "tax_number": {
                          "type": "string",
                          "nullable": true,
                          "example": "GB412 8925 93"
                        },
                        "risk_level": {
                          "type": "string",
                          "nullable": true,
                          "description": "Tingkat risiko yang dilaporkan registri, jika tersedia."
                        },
                        "verification_status": {
                          "type": "string",
                          "enum": [
                            "verified",
                            "failed",
                            "unknown"
                          ],
                          "nullable": true,
                          "description": "Status verifikasi lintas yurisdiksi: `verified` ketika status registri menetapkan status hukum aktif (`active`), `failed` ketika menyatakan bahwa perusahaan tidak lagi berstatus baik (misalnya `dissolved`), jika tidak maka `unknown`. Bernilai `null` untuk perusahaan yang tidak berasal dari registri dan selama pemilihan masih `pending`."
                        },
                        "is_from_registry": {
                          "type": "boolean",
                          "description": "Selalu `true` untuk endpoint ini — profil diambil dari registri resmi."
                        },
                        "fetch_status": {
                          "type": "string",
                          "enum": [
                            "pending",
                            "resolved"
                          ],
                          "description": "Siklus hidup pengambilan registri. Dicerminkan oleh `data_resolved`."
                        },
                        "alternative_names": {
                          "type": "string",
                          "nullable": true,
                          "description": "Nama perusahaan alternatif, nama dagang, nama terdahulu, atau nama dalam bahasa asli sebagai teks, jika dilaporkan."
                        },
                        "nature_of_business": {
                          "type": "string",
                          "nullable": true,
                          "description": "Deskripsi aktivitas atau kode klasifikasi, jika dilaporkan."
                        },
                        "registered_capital": {
                          "type": "string",
                          "nullable": true
                        },
                        "registered_capital_amount": {
                          "type": "string",
                          "nullable": true,
                          "description": "Jumlah desimal sebagai string, saat dilaporkan."
                        },
                        "registered_capital_currency": {
                          "type": "string",
                          "nullable": true,
                          "description": "Kode ISO 4217, saat dilaporkan."
                        },
                        "website": {
                          "type": "string",
                          "nullable": true,
                          "example": "https://www.tesco.com/"
                        },
                        "email": {
                          "type": "string",
                          "nullable": true,
                          "example": "customer.service@tesco.co.uk"
                        },
                        "phone": {
                          "type": "string",
                          "nullable": true,
                          "example": "03301231688"
                        },
                        "legal_entity_identifier": {
                          "type": "string",
                          "nullable": true,
                          "description": "LEI, jika dilaporkan."
                        },
                        "location_of_registration": {
                          "type": "string",
                          "nullable": true,
                          "description": "Registri/yurisdiksi tempat perusahaan terdaftar, jika dilaporkan."
                        },
                        "vat_number": {
                          "type": "string",
                          "nullable": true,
                          "description": "Nomor PPN Uni Eropa, saat dikumpulkan selama langkah registri yang di-hosting atau diedit sesudahnya. Saat dipilih, nilai ini biasanya belum ditetapkan — validasi PPN dan ID pajak dijalankan ketika pengguna akhir mengirimkan langkah registri dalam alur yang di-hosting."
                        },
                        "vat_validation_status": {
                          "type": "string",
                          "enum": [
                            "valid",
                            "invalid",
                            "format_valid",
                            "invalid_format",
                            "could_not_validate",
                            "not_applicable"
                          ],
                          "description": "Hasil validasi nomor PPN atau, jika tidak ada, `tax_number`, saat pengiriman ke registri. `valid` / `invalid`: ditentukan oleh registri resmi negara (EU VIES, Norwegia, Swiss, Brasil, Kolombia, Kosta Rika, Ekuador, Paraguay; Polandia juga melalui registri PPN domestiknya). `format_valid` / `invalid_format`: ditentukan oleh aturan format dan digit centang negara tersebut jika tidak ada registri yang dapat dikueri. `could_not_validate`: registri tidak tersedia. `not_applicable`: tidak ada nomor, negara tanpa registri atau aturan, atau sesi sandbox."
                        },
                        "vat_validated_number": {
                          "type": "string",
                          "nullable": true,
                          "description": "Nomor yang diperiksa, sebagaimana diketahui oleh sumber (misalnya nomor PPN yang diperoleh dari SIREN Prancis atau RSIN Belanda). `null` jika tidak ada pemeriksaan yang dijalankan."
                        },
                        "vat_validation_source": {
                          "type": "string",
                          "nullable": true,
                          "enum": [
                            "eu_vies",
                            "pl_vat_white_list",
                            "no_brreg",
                            "ch_uid_register",
                            "br_receita_federal",
                            "co_rues",
                            "cr_hacienda",
                            "ec_sri",
                            "py_dnit",
                            "format_rules",
                            null
                          ],
                          "description": "Sumber yang menentukan `vat_validation_status`: registri resmi, atau `format_rules`. `null` jika tidak ada pemeriksaan yang dijalankan."
                        },
                        "vat_validated_name": {
                          "type": "string",
                          "nullable": true,
                          "description": "Nama yang terdaftar pada sumber yang memvalidasi nomor tersebut, jika menyediakannya. Hanya ditetapkan saat statusnya `valid`."
                        },
                        "vat_validated_address": {
                          "type": "string",
                          "nullable": true,
                          "description": "Alamat yang terdaftar pada sumber yang memvalidasi nomor tersebut, jika sumber mengungkapkannya. Hanya diisi jika statusnya `valid`."
                        },
                        "vat_checked_at": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true,
                          "description": "Cap waktu pemeriksaan. `null` jika tidak ada pemeriksaan yang dilakukan."
                        },
                        "financial_summary": {
                          "type": "object",
                          "nullable": true,
                          "description": "Detail saham/modal yang dilaporkan registri (mata uang, total saham, kelas saham), jika tersedia."
                        },
                        "officers": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "uuid": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "name": {
                                "type": "string",
                                "example": "MELISSA BETHELL"
                              },
                              "designation": {
                                "type": "string",
                                "nullable": true,
                                "description": "Penetapan registri mentah (misalnya `Director`, `Secretary`)."
                              },
                              "role": {
                                "type": "string",
                                "description": "Peran yang dinormalisasi yang diturunkan dari sebutan. Kumpulan model 17 nilai lengkap; penguraian registri pada endpoint ini biasanya menghasilkan director, non_executive_director, secretary, chairman, atau company_officer.",
                                "enum": [
                                  "director",
                                  "non_executive_director",
                                  "secretary",
                                  "chairman",
                                  "ubo",
                                  "shareholder",
                                  "representative",
                                  "founder",
                                  "legal_advisor",
                                  "authorized_signatory",
                                  "trustee",
                                  "beneficiary",
                                  "company_officer",
                                  "settlor",
                                  "protector",
                                  "investor",
                                  "other"
                                ]
                              },
                              "nationality": {
                                "type": "string",
                                "nullable": true
                              },
                              "is_active": {
                                "type": "boolean",
                                "description": "`false` saat registri menandai pengangkatan telah berakhir karena pengunduran diri."
                              },
                              "kyc_status": {
                                "type": "string",
                                "nullable": true,
                                "enum": [
                                  "Approved",
                                  "Declined",
                                  "Pending"
                                ],
                                "description": "Status sesi KYC terkait, jika ada yang dimulai untuk pejabat ini. Jika tidak, bernilai `null`."
                              },
                              "kyc_session_url": {
                                "type": "string",
                                "nullable": true,
                                "description": "URL verifikasi dari sesi KYC terkait, jika ada."
                              },
                              "first_name": {
                                "type": "string",
                                "nullable": true,
                                "description": "Nama depan ketika dilaporkan secara eksplisit oleh registri; tidak disimpulkan dari nama lengkap."
                              },
                              "last_name": {
                                "type": "string",
                                "nullable": true,
                                "description": "Nama keluarga ketika dilaporkan secara eksplisit oleh registri."
                              },
                              "address": {
                                "type": "string",
                                "nullable": true,
                                "description": "Alamat pejabat yang dilaporkan oleh registri."
                              },
                              "appointment_date": {
                                "type": "string",
                                "nullable": true,
                                "description": "Tanggal petugas diangkat.",
                                "format": "date"
                              },
                              "termination_date": {
                                "type": "string",
                                "nullable": true,
                                "description": "Tanggal pengangkatan berakhir, jika dilaporkan.",
                                "format": "date"
                              },
                              "date_of_birth": {
                                "type": "string",
                                "nullable": true,
                                "description": "Tanggal lahir lengkap yang dilaporkan registri. Bernilai null jika hanya tahun atau bulan lahir yang diketahui.",
                                "format": "date"
                              },
                              "date_of_birth_year": {
                                "type": "integer",
                                "nullable": true,
                                "minimum": 1,
                                "maximum": 9999,
                                "description": "Tahun lahir yang dilaporkan registri, termasuk saat tanggal lengkap tidak tersedia."
                              },
                              "date_of_birth_month": {
                                "type": "integer",
                                "nullable": true,
                                "minimum": 1,
                                "maximum": 12,
                                "description": "Bulan lahir yang dilaporkan registri. Null jika hanya tahun yang diketahui."
                              }
                            }
                          },
                          "description": "Direktur, sekretaris, dan petugas lainnya yang diekstrak dari registri."
                        },
                        "beneficial_owners": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "uuid": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "name": {
                                "type": "string"
                              },
                              "first_name": {
                                "type": "string",
                                "nullable": true
                              },
                              "last_name": {
                                "type": "string",
                                "nullable": true
                              },
                              "entity_type": {
                                "type": "string",
                                "enum": [
                                  "person",
                                  "company"
                                ],
                                "description": "Apakah pemiliknya adalah perorangan atau entitas korporat."
                              },
                              "roles": {
                                "type": "array",
                                "items": {
                                  "type": "string"
                                },
                                "description": "Peran yang dinormalisasi (misalnya `ubo`, `shareholder`)."
                              },
                              "ownership_min_shares": {
                                "type": "string",
                                "nullable": true,
                                "description": "Batas bawah rentang kepemilikan yang dilaporkan oleh registri (misalnya `25%`)."
                              },
                              "ownership_max_shares": {
                                "type": "string",
                                "nullable": true,
                                "description": "Batas atas rentang kepemilikan yang dilaporkan oleh registri."
                              },
                              "is_active": {
                                "type": "boolean"
                              },
                              "kyc_status": {
                                "type": "string",
                                "nullable": true,
                                "enum": [
                                  "Approved",
                                  "Declined",
                                  "Pending"
                                ]
                              },
                              "kyc_session_url": {
                                "type": "string",
                                "nullable": true
                              },
                              "effective_ownership_percent": {
                                "type": "number",
                                "nullable": true,
                                "description": "Persentase kepemilikan terurai (batas maksimum, beralih ke batas minimum jika tidak ada)."
                              },
                              "company_name": {
                                "type": "string",
                                "nullable": true
                              },
                              "registration_number": {
                                "type": "string",
                                "nullable": true
                              },
                              "country_of_birth": {
                                "type": "string",
                                "nullable": true
                              },
                              "email": {
                                "type": "string",
                                "nullable": true
                              },
                              "nationality": {
                                "type": "string",
                                "nullable": true
                              },
                              "designation": {
                                "type": "string",
                                "nullable": true
                              },
                              "voting_min_shares": {
                                "type": "string",
                                "nullable": true
                              },
                              "voting_max_shares": {
                                "type": "string",
                                "nullable": true
                              },
                              "date_of_birth": {
                                "type": "string",
                                "nullable": true,
                                "description": "Tanggal lahir lengkap jika dilaporkan.",
                                "format": "date"
                              },
                              "appointment_date": {
                                "type": "string",
                                "nullable": true,
                                "description": "Tanggal penunjukan saat dilaporkan.",
                                "format": "date"
                              },
                              "shareholding": {
                                "$ref": "#/components/schemas/KYBRegistryShareholding"
                              }
                            }
                          },
                          "description": "Pemilik manfaat / pihak dengan kendali signifikan yang diekstrak dari registri. Dapat bernilai kosong jika registri tidak mencantumkan kepemilikan."
                        },
                        "addresses": {
                          "type": "array",
                          "nullable": true,
                          "description": "Setiap alamat yang dinyatakan oleh registri, satu bentuk kanonikal. Null jika tidak ada yang dinyatakan.",
                          "items": {
                            "$ref": "#/components/schemas/KYBRegistryAddress"
                          }
                        },
                        "industries": {
                          "type": "array",
                          "nullable": true,
                          "description": "Aktivitas yang diklasifikasikan oleh registri untuk perusahaan, dalam satu format kanonis. Bernilai null jika tidak ada yang dinyatakan.",
                          "items": {
                            "$ref": "#/components/schemas/KYBRegistryIndustry"
                          }
                        },
                        "accounts": {
                          "type": "object",
                          "nullable": true,
                          "additionalProperties": true,
                          "description": "Tanggal pengajuan registri, jika tersedia. Laporan tahunan dan rapat umum menggunakan last_annual_return_date dan last_agm_date; keduanya berbeda dari laporan keuangan."
                        },
                        "registry_data": {
                          "$ref": "#/components/schemas/KYBRegistryData"
                        },
                        "user_provided_data": {
                          "type": "object",
                          "nullable": true,
                          "description": "Selalu `null` pada endpoint ini (digunakan oleh alur KYB yang di-hosting saat pengguna akhir mengedit data registri)."
                        },
                        "confirmed_by_user_at": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true,
                          "description": "Selalu `null` pada endpoint ini."
                        },
                        "last_console_edit_at": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true,
                          "description": "Ditetapkan saat peninjau konsol mengedit catatan tersebut nanti."
                        },
                        "is_editable": {
                          "type": "boolean",
                          "description": "Apakah data yang bersumber dari registri masih dapat diedit di alur yang di-hosting atau di konsol."
                        },
                        "registry_tier_delivered": {
                          "type": "string",
                          "enum": [
                            "basic",
                            "shareholders",
                            "ubo"
                          ],
                          "description": "Sama dengan `registry_tier_delivered` di tingkat teratas."
                        },
                        "registry_ownership_status": {
                          "type": "string",
                          "nullable": true,
                          "enum": [
                            "not_requested",
                            "delivered",
                            "not_held",
                            "unavailable"
                          ],
                          "description": "`delivered` saat data kepemilikan berhasil diperoleh, `not_held` saat registri kepemilikan merespons dan tidak mencantumkan perusahaan ini (lihat `registry_data.ownership_error`), `unavailable` saat tingkat kepemilikan diminta tetapi registri tidak memilikinya untuk perusahaan ini atau tidak dapat dimintai keterangan (lihat `registry_data.ownership_error`), `not_requested` pada tingkat Lite."
                        },
                        "ownership": {
                          "$ref": "#/components/schemas/KYBRegistryOwnership"
                        },
                        "registry_tier": {
                          "type": "string",
                          "nullable": true,
                          "description": "Tingkat registri yang dipesan oleh alur kerja: `basic`, `shareholders`, atau `ubo`. Juga terdapat di `ownership.tier_requested`."
                        },
                        "registry_monitoring": {
                          "type": "object",
                          "nullable": true,
                          "description": "Pemantau registri terbaru untuk perusahaan, atau `null` jika tidak ada.",
                          "properties": {
                            "uuid": {
                              "type": "string",
                              "format": "uuid"
                            },
                            "status": {
                              "type": "string"
                            },
                            "unavailable_reason": {
                              "type": "string",
                              "nullable": true
                            },
                            "enrolled_at": {
                              "type": "string",
                              "format": "date-time",
                              "nullable": true
                            },
                            "cancelled_at": {
                              "type": "string",
                              "format": "date-time",
                              "nullable": true
                            },
                            "last_bill_date": {
                              "type": "string",
                              "format": "date",
                              "nullable": true
                            },
                            "next_bill_date": {
                              "type": "string",
                              "format": "date",
                              "nullable": true
                            },
                            "last_event_at": {
                              "type": "string",
                              "format": "date-time",
                              "nullable": true
                            },
                            "events_count": {
                              "type": "integer"
                            },
                            "watched_fields": {
                              "description": "Kolom perusahaan yang dipantau oleh pemantau."
                            }
                          }
                        }
                      }
                    },
                    "vendor_data": {
                      "type": "string",
                      "nullable": true,
                      "description": "Menampilkan kembali `vendor_data` yang Anda kirimkan."
                    },
                    "metadata": {
                      "type": "object",
                      "nullable": true,
                      "description": "Salinan `metadata` yang Anda kirimkan."
                    },
                    "created_at": {
                      "type": "string",
                      "format": "date-time"
                    }
                  }
                },
                "examples": {
                  "Resolved company": {
                    "summary": "Profil registri lengkap (daftar pejabat dipersingkat untuk menghemat tempat)",
                    "value": {
                      "request_id": "9d4f2c7a-1b3e-4a5c-8d6f-0e9a8b7c6d5e",
                      "kyb_registry": {
                        "uuid": "f1e2d3c4-b5a6-4789-9c0d-1e2f3a4b5c6d",
                        "node_id": "feature_kyb_registry",
                        "status": "In Review",
                        "registry_status": "active",
                        "data_resolved": true,
                        "company_name": "Tesco PLC",
                        "registration_number": "00445790",
                        "country_code": "GB",
                        "region": "",
                        "company_type": "Public Limited Company",
                        "incorporation_date": "1947-11-27",
                        "registered_address": "Tesco House, Shire Park, Kestrel Way, Welwyn Garden City, United Kingdom, AL7 1GA",
                        "tax_number": "GB412 8925 93",
                        "risk_level": "low risk",
                        "verification_status": "verified",
                        "is_from_registry": true,
                        "fetch_status": "resolved",
                        "alternative_names": "TESCO STORES (HOLDINGS) PUBLIC LIMITED COMPANY",
                        "nature_of_business": null,
                        "registered_capital": null,
                        "registered_capital_amount": null,
                        "registered_capital_currency": null,
                        "website": "https://www.tesco.com/",
                        "email": "customer.service@tesco.co.uk",
                        "phone": "03301231688",
                        "legal_entity_identifier": null,
                        "location_of_registration": null,
                        "financial_summary": {
                          "currency": "Pound (£)",
                          "total_number_of_shares": "8174378721",
                          "meta_detail": {
                            "Class_Of_Share": "Ordinary"
                          }
                        },
                        "officers": [
                          {
                            "uuid": "a1b2c3d4-e5f6-4789-9a0b-1c2d3e4f5a6b",
                            "name": "CHRISTOPHER JON TAYLOR",
                            "designation": "Secretary",
                            "role": "secretary",
                            "nationality": null,
                            "is_active": true,
                            "kyc_status": null,
                            "kyc_session_url": null
                          },
                          {
                            "uuid": "b2c3d4e5-f6a7-4890-8b1c-2d3e4f5a6b7c",
                            "name": "MELISSA BETHELL",
                            "designation": "Director",
                            "role": "director",
                            "nationality": "British",
                            "is_active": true,
                            "kyc_status": null,
                            "kyc_session_url": null
                          }
                        ],
                        "beneficial_owners": [],
                        "addresses": [
                          {
                            "address": "Tesco House, Shire Park, Kestrel Way, Welwyn Garden City, United Kingdom, AL7 1GA",
                            "type": "legal_entity_registry_address",
                            "description": "registered office address"
                          }
                        ],
                        "industries": null,
                        "accounts": {
                          "last_account": "26 February 2025",
                          "next_account": "26 February 2026",
                          "due_by_date": "26 August 2026"
                        },
                        "registry_data": {},
                        "user_provided_data": null,
                        "confirmed_by_user_at": null,
                        "last_console_edit_at": null,
                        "is_editable": true
                      },
                      "vendor_data": "company-1234",
                      "metadata": null,
                      "created_at": "2026-06-11T10:45:00.000000+00:00"
                    }
                  },
                  "Pending (registry still resolving)": {
                    "summary": "Select tetap pending setelah polling — kolom yang tersedia hanya sebagian, dilengkapi secara otomatis di sisi server",
                    "value": {
                      "request_id": "9d4f2c7a-1b3e-4a5c-8d6f-0e9a8b7c6d5e",
                      "kyb_registry": {
                        "uuid": "7c0a4f7e-2b1d-4f6a-9c3e-8d5b2a1f0e9d",
                        "node_id": "feature_kyb_registry",
                        "status": "Not Finished",
                        "registry_status": null,
                        "data_resolved": false,
                        "company_name": "Tesco PLC",
                        "registration_number": "00445790",
                        "country_code": "GB",
                        "region": null,
                        "company_type": null,
                        "incorporation_date": null,
                        "registered_address": null,
                        "tax_number": null,
                        "risk_level": null,
                        "verification_status": null,
                        "is_from_registry": true,
                        "fetch_status": "pending",
                        "alternative_names": null,
                        "nature_of_business": null,
                        "registered_capital": null,
                        "registered_capital_amount": null,
                        "registered_capital_currency": null,
                        "website": null,
                        "email": null,
                        "phone": null,
                        "legal_entity_identifier": null,
                        "location_of_registration": null,
                        "financial_summary": {},
                        "officers": [],
                        "beneficial_owners": [],
                        "addresses": null,
                        "industries": null,
                        "accounts": null,
                        "registry_data": {},
                        "user_provided_data": null,
                        "confirmed_by_user_at": null,
                        "last_console_edit_at": null,
                        "is_editable": true
                      },
                      "vendor_data": "company-1234",
                      "metadata": null,
                      "created_at": "2026-06-11T10:45:00.000000+00:00"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Kesalahan validasi. Masalah tingkat kolom menggunakan format standar DRF. Negara yang tidak dicakup oleh registri menghasilkan respons `400` dengan `code: kyb_registry_country_unsupported`.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing kyb_response_id": {
                    "summary": "`kyb_response_id` diperlukan",
                    "value": {
                      "kyb_response_id": [
                        "This field is required."
                      ]
                    }
                  },
                  "save_api_request=false rejected": {
                    "summary": "Pilihan selalu disimpan",
                    "value": {
                      "save_api_request": [
                        "KYB registry select must be saved so billing and retrieval can be tracked."
                      ]
                    }
                  },
                  "Country not covered": {
                    "summary": "Tidak ada registri perusahaan yang mencakup negara tersebut",
                    "value": {
                      "detail": "Company registry search is not available for this country. Enter the company details manually to continue.",
                      "code": "kyb_registry_country_unsupported"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Izin ditolak. Dikembalikan ketika header `x-api-key` tidak ada, dan juga ketika saldo organisasi pemanggil tidak dapat mencukupi biaya panggilan tersebut; kunci yang salah, dicabut, atau kedaluwarsa mengembalikan `401`. Kunci yang tidak ada mengembalikan `403` dengan `{\"detail\": ...}`; kunci yang salah, dicabut, atau kedaluwarsa mengembalikan `401`. Kekurangan kredit mengembalikan `403` dengan `{\"error\": ...}` sebelum skrining atau panggilan penyedia apa pun terjadi.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing or invalid API key": {
                    "summary": "Tidak ada header `x-api-key`, atau kuncinya tidak valid/dicabut",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Not enough credits": {
                    "summary": "Saldo organisasi tidak mencukupi untuk panggilan ini",
                    "value": {
                      "error": "You don't have enough credits to perform this request. Please top up at https://business.didit.me"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Batas laju terlampaui. Endpoint POST/PATCH/DELETE berbagi anggaran 300 permintaan penulisan per menit per kunci API (pembuatan transaksi dan ingesti event memiliki anggaran terpisah sebesar 600). Respons menyertakan header `X-RateLimit-Limit`, `X-RateLimit-Remaining`, `X-RateLimit-Reset`, dan `Retry-After`.",
            "content": {
              "application/json": {
                "examples": {
                  "Write rate limit exceeded": {
                    "summary": "Lebih dari 300 permintaan tulis pada menit ini",
                    "value": {
                      "detail": "Write request rate limit exceeded. You can make up to 300 requests per minute."
                    }
                  }
                },
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v3/passive-liveness/": {
      "post": {
        "summary": "Liveness Pasif",
        "description": "Deteksi serangan presentasi — foto cetak, pemutaran ulang layar, topeng, deepfake — dari satu gambar wajah. Tidak memerlukan video, gerakan, atau interaksi pengguna.\n\n**Cara kerjanya.** Gambar dianalisis oleh model biometrik; wajah terbesar yang terdeteksi dievaluasi dan `score` liveness (0–100) dihitung. `status` bernilai `Declined` ketika salah satu peringatan dengan tingkat keparahan `error` terpicu:\n- `NO_FACE_DETECTED` — model liveness tidak menemukan wajah,\n- `LOW_LIVENESS_SCORE` — skor sama dengan atau di bawah `face_liveness_score_decline_threshold` (default `30`),\n- `LIVENESS_FACE_ATTACK` — model mendeteksi serangan presentasi,\n- `FACE_IN_BLOCKLIST` / `POSSIBLE_FACE_IN_BLOCKLIST` — wajah cocok dengan entri pada daftar blokir wajah Anda.\n\n`MULTIPLE_FACES_DETECTED` adalah sinyal tingkat keparahan `warning` (tidak menolak), dan `DUPLICATED_FACE` / `POSSIBLE_DUPLICATED_FACE` adalah sinyal tingkat keparahan `information` bahwa wajah yang sama telah muncul di sesi lain yang disetujui (sinyal ini tidak pernah menolak). `face_quality` dan `face_luminance` (0–100, nullable) menjelaskan kualitas pengambilan gambar.\n\n**Skrining daftar blokir dan duplikat.** Berjalan pada **setiap** panggilan — dengan atau tanpa `save_api_request` — dengan mencocokkan wajah yang terdeteksi terhadap indeks pencarian wajah aplikasi Anda. Wajah sebelumnya dengan `vendor_data` yang sama dikecualikan dari seluruh pencarian indeks — sehingga menjalankan ulang liveness untuk pengguna yang sama tidak memicu `DUPLICATED_FACE`, dan wajah dalam daftar blokir yang berasal dari sesi dengan `vendor_data` milik pemanggil sendiri juga TIDAK ditandai (skrining `FACE_IN_BLOCKLIST` dilewati untuk wajah dengan `vendor_data` yang sama).\n\n**Penagihan.** Setiap respons `200` menggunakan satu kredit Passive Liveness API (dibayar dari kredit paket atau saldo isi ulang Anda). Saldo yang tidak mencukupi mengembalikan `403` sebelum pemrosesan gambar apa pun.\n\n**Persistensi sesi dan pendaftaran wajah (`save_api_request`, default `true`).** Jika bernilai `true`, panggilan disimpan sebagai sesi bertipe API (Business Console, `GET /v3/session/{sessionId}/decision/` melalui `request_id` yang dikembalikan, webhook `status.updated`), gambar referensi dan potongan wajah disimpan, dan wajah yang terdeteksi **didaftarkan ke dalam indeks pencarian wajah Anda** sehingga panggilan Pencarian Wajah dan pemeriksaan duplikat di kemudian hari dapat mencocokkannya. Jika bernilai `false`, panggilan bersifat sekali pakai: tidak ada yang disimpan dan wajah tidak didaftarkan (skrining daftar blokir/duplikat tetap berjalan).\n\n**Sandbox.** Kunci API sandbox melewati semua pemrosesan dan penagihan: setelah validasi permintaan (input yang salah tetap mengembalikan `400`), endpoint mengembalikan payload tiruan `Approved` statis, tidak ada sesi yang disimpan, dan tidak ada kredit yang digunakan.\n\n**Autentikasi.** Kirim kunci API aplikasi Anda di header `x-api-key`. Kredensial yang hilang atau tidak valid mengembalikan `403` (`{\"detail\": \"You do not have permission to perform this action.\"}`) — API ini tidak pernah mengembalikan `401`.\n\n**Batas laju.** Kuota penulisan bersama sebesar 300 permintaan/menit per kunci API di seluruh endpoint POST/PATCH/DELETE; melampauinya akan mengembalikan `429`.",
        "operationId": "post_v3passive-liveness",
        "x-didit-sdk": {
          "resource": "passive_liveness",
          "method": "check",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Standalone APIs"
        ],
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "required": [
                  "user_image"
                ],
                "properties": {
                  "user_image": {
                    "type": "string",
                    "format": "binary",
                    "description": "Gambar wajah menghadap ke depan (misalnya swafoto). Ekstensi yang diizinkan: `tiff`, `jpg`, `jpeg`, `png`, `webp`. Ukuran unggahan maksimum: **5 MB** (file yang lebih besar ditolak dengan `400`). Gambar otomatis dikompresi menjadi ~0.5 MB sebelum diproses, sehingga resolusi yang sangat tinggi tidak meningkatkan akurasi. Gambar harus memuat satu subjek — jika terdapat beberapa wajah, wajah terbesar yang akan dievaluasi dan peringatan `MULTIPLE_FACES_DETECTED` ditambahkan."
                  },
                  "face_liveness_score_decline_threshold": {
                    "type": "number",
                    "format": "float",
                    "default": 30,
                    "minimum": 0,
                    "maximum": 100,
                    "description": "Ambang batas skor liveness (0–100). Skor terhitung **pada atau di bawah** nilai ini mengeluarkan peringatan `LOW_LIVENESS_SCORE` dan menetapkan `status` ke `Declined`. Default `30`; naikkan untuk postur anti-spoofing yang lebih ketat. Nilai di luar 0–100 mengembalikan `400`.",
                    "example": 30
                  },
                  "rotate_image": {
                    "type": "boolean",
                    "default": false,
                    "description": "Jika `true`, layanan mencoba rotasi 90 derajat dari input dan menggunakan orientasi yang menghasilkan deteksi wajah terbaik. Berguna saat orientasi EXIF tidak ada. Menambah latensi.",
                    "example": false
                  },
                  "save_api_request": {
                    "type": "boolean",
                    "default": true,
                    "description": "Jika `true` (default), menyimpan panggilan sebagai sesi tipe API, menyimpan gambar wajah, memancarkan webhook `status.updated`, dan mendaftarkan wajah yang terdeteksi ke dalam indeks pencarian wajah Anda. Jika `false`, panggilan bersifat sekali jalan — tidak ada yang disimpan dan wajah tidak didaftarkan. Skrining daftar blokir dan duplikat tetap berjalan di kedua kondisi.",
                    "example": true
                  },
                  "vendor_data": {
                    "type": "string",
                    "description": "Pengidentifikasi buram opsional (ID pengguna, email, UUID Anda…) yang disimpan pada sesi yang dipertahankan dan dikembalikan. Juga digunakan untuk mengecualikan sesi sebelumnya dengan `vendor_data` yang sama dari pemeriksaan wajah duplikat, sehingga verifikasi ulang pengguna yang sama tidak memicu `DUPLICATED_FACE`.",
                    "example": "user-123"
                  },
                  "metadata": {
                    "type": "object",
                    "additionalProperties": true,
                    "description": "Objek JSON opsional yang disimpan bersama sesi (saat `save_api_request=true`) dan dikembalikan. Dalam permintaan multipart, kirimkan sebagai kolom string berenkode JSON — kolom ini akan diuraikan menjadi sebuah objek.",
                    "example": {
                      "flow": "withdrawal"
                    }
                  }
                }
              },
              "example": {
                "user_image": "(binary JPEG/PNG selfie)",
                "face_liveness_score_decline_threshold": 30,
                "rotate_image": false,
                "save_api_request": true,
                "vendor_data": "user-123",
                "metadata": {
                  "flow": "withdrawal"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Deteksi liveness pasif selesai. `liveness.score` adalah tingkat keyakinan model 0–100 bahwa gambar tersebut menampilkan orang sungguhan; `status` bernilai `Approved` kecuali jika peringatan berbobot `error` terpicu. Wajah hasil spoofing atau yang masuk daftar blokir tetap mengembalikan `200` — periksa `liveness.status` dan `liveness.warnings`, bukan hanya kode HTTP. Ketika `save_api_request=true`, `request_id` adalah ID sesi yang disimpan.",
            "content": {
              "application/json": {
                "examples": {
                  "Approved": {
                    "summary": "Wajah nyata — tidak ada peringatan",
                    "value": {
                      "request_id": "a1b2c3d4-e5f6-7890-1234-567890abcdef",
                      "liveness": {
                        "status": "Approved",
                        "method": "PASSIVE",
                        "score": 95.0,
                        "user_image": {
                          "entities": [
                            {
                              "bbox": [
                                661,
                                728,
                                1688,
                                2188
                              ],
                              "confidence": 0.732973,
                              "age": 26.91,
                              "gender": "male",
                              "race": null
                            }
                          ],
                          "best_angle": 0
                        },
                        "warnings": [],
                        "face_quality": 84.21,
                        "face_luminance": 50.33
                      },
                      "vendor_data": "user-123",
                      "metadata": null,
                      "created_at": "2026-06-12T01:04:42.763237+00:00"
                    }
                  },
                  "Declined - presentation attack": {
                    "summary": "Model menandai adanya spoofing (cetak, tayang ulang, topeng…)",
                    "value": {
                      "request_id": "f1c8c9b2-d3e4-4f5a-9b8c-7d6e5f4a3b2c",
                      "liveness": {
                        "status": "Declined",
                        "method": "PASSIVE",
                        "score": 12.5,
                        "user_image": {
                          "entities": [
                            {
                              "bbox": [
                                100,
                                120,
                                420,
                                540
                              ],
                              "confidence": 0.81,
                              "age": 30.1,
                              "gender": "female",
                              "race": null
                            }
                          ],
                          "best_angle": 0
                        },
                        "warnings": [
                          {
                            "risk": "LOW_LIVENESS_SCORE",
                            "feature": "LIVENESS",
                            "additional_data": null,
                            "log_type": "error",
                            "short_description": "Low liveness score",
                            "long_description": "The liveness check resulted in a low score, indicating potential use of non-live facial representations or poor-quality biometric data."
                          },
                          {
                            "risk": "LIVENESS_FACE_ATTACK",
                            "feature": "LIVENESS",
                            "additional_data": null,
                            "log_type": "error",
                            "short_description": "Liveness Face Attack",
                            "long_description": "The system detected a potential attempt to bypass the liveness check."
                          }
                        ],
                        "face_quality": 72.4,
                        "face_luminance": 48.2
                      },
                      "vendor_data": "user-123",
                      "metadata": null,
                      "created_at": "2026-06-12T01:04:42.763237+00:00"
                    }
                  },
                  "Declined - face on blocklist": {
                    "summary": "Wajah nyata, tetapi cocok dengan entri daftar blokir",
                    "value": {
                      "request_id": "0b54a1de-22aa-4e0f-9c84-5a2b1f3c4d5e",
                      "liveness": {
                        "status": "Declined",
                        "method": "PASSIVE",
                        "score": 93.75,
                        "user_image": {
                          "entities": [
                            {
                              "bbox": [
                                40,
                                40,
                                100,
                                100
                              ],
                              "confidence": 0.722082,
                              "age": 27.0,
                              "gender": "male",
                              "race": null
                            }
                          ],
                          "best_angle": 0
                        },
                        "warnings": [
                          {
                            "risk": "FACE_IN_BLOCKLIST",
                            "feature": "LIVENESS",
                            "additional_data": {
                              "blocklisted_session_id": "882c42d5-8a4d-4d20-8080-a22f57822c86",
                              "blocklisted_session_number": 3242,
                              "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."
                          }
                        ],
                        "face_quality": null,
                        "face_luminance": null
                      },
                      "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": "ID sesi yang disimpan saat `save_api_request=true` (dapat digunakan dengan `GET /v3/session/{sessionId}/decision/`); jika tidak, berupa UUID korelasi sementara."
                    },
                    "liveness": {
                      "type": "object",
                      "properties": {
                        "status": {
                          "type": "string",
                          "enum": [
                            "Approved",
                            "Declined"
                          ],
                          "description": "`Declined` ketika setidaknya satu peringatan berperingkat `error` terpicu (tidak ada wajah, skor rendah, serangan presentasi, atau kecocokan daftar blokir); `Approved` jika tidak. Entri `warning`/`information` (banyak wajah, duplikat) tidak pernah menolak dengan sendirinya."
                        },
                        "method": {
                          "type": "string",
                          "enum": [
                            "PASSIVE"
                          ],
                          "description": "Selalu `PASSIVE` untuk endpoint ini."
                        },
                        "score": {
                          "type": "number",
                          "format": "float",
                          "nullable": true,
                          "minimum": 0,
                          "maximum": 100,
                          "description": "Keyakinan liveness (0–100, dua desimal) bahwa gambar menampilkan orang sungguhan, bukan spoofing. `null` jika model tidak mengembalikan keyakinan.",
                          "example": 95.0
                        },
                        "user_image": {
                          "type": "object",
                          "description": "Hasil deteksi wajah untuk gambar yang dikirimkan.",
                          "properties": {
                            "entities": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "bbox": {
                                    "type": "array",
                                    "items": {
                                      "type": "integer"
                                    },
                                    "minItems": 4,
                                    "maxItems": 4,
                                    "description": "Bounding box wajah yang terdeteksi sebagai koordinat piksel `[x_min, y_min, x_max, y_max]` pada gambar yang diproses.",
                                    "example": [
                                      661,
                                      728,
                                      1688,
                                      2188
                                    ]
                                  },
                                  "confidence": {
                                    "type": "number",
                                    "format": "float",
                                    "minimum": 0,
                                    "maximum": 1,
                                    "description": "Skor keyakinan deteksi wajah (0–1).",
                                    "example": 0.732973
                                  },
                                  "age": {
                                    "type": "number",
                                    "format": "float",
                                    "description": "Usia yang diestimasi model dari wajah yang terdeteksi, dalam tahun. Hanya bersifat informasi — ini tidak memengaruhi keputusan liveness.",
                                    "example": 26.91
                                  },
                                  "gender": {
                                    "type": "string",
                                    "description": "Jenis kelamin yang diprediksi oleh model dari wajah yang terdeteksi (`male` atau `female`). Hanya bersifat informasi.",
                                    "example": "male"
                                  },
                                  "race": {
                                    "type": "string",
                                    "nullable": true,
                                    "description": "Kolom yang dicadangkan — selalu bernilai `null` dalam respons dari endpoint ini.",
                                    "example": null
                                  }
                                }
                              },
                              "description": "Satu entri per wajah yang terdeteksi. Wajah terbesar adalah wajah yang dievaluasi."
                            },
                            "best_angle": {
                              "type": "integer",
                              "nullable": true,
                              "description": "Rotasi (derajat) yang menghasilkan deteksi wajah terbaik; bernilai bukan nol hanya ketika `rotate_image=true` mengoreksi orientasi.",
                              "example": 0
                            }
                          }
                        },
                        "warnings": {
                          "type": "array",
                          "description": "Sinyal risiko. Keparahan `error` (penolakan): `NO_FACE_DETECTED`, `LOW_LIVENESS_SCORE` (skor pada atau di bawah ambang batas), `LIVENESS_FACE_ATTACK`, `FACE_IN_BLOCKLIST`, `POSSIBLE_FACE_IN_BLOCKLIST`. Keparahan `warning` (peninjauan, tanpa penolakan): `MULTIPLE_FACES_DETECTED`. Keparahan `information` (tanpa penolakan): `DUPLICATED_FACE`, `POSSIBLE_DUPLICATED_FACE` — wajah yang sama telah muncul di sesi lain yang disetujui.",
                          "items": {
                            "type": "object",
                            "properties": {
                              "risk": {
                                "type": "string",
                                "enum": [
                                  "NO_FACE_DETECTED",
                                  "LOW_LIVENESS_SCORE",
                                  "LIVENESS_FACE_ATTACK",
                                  "MULTIPLE_FACES_DETECTED",
                                  "FACE_IN_BLOCKLIST",
                                  "POSSIBLE_FACE_IN_BLOCKLIST",
                                  "DUPLICATED_FACE",
                                  "POSSIBLE_DUPLICATED_FACE"
                                ],
                                "description": "Kode risiko yang dapat dibaca mesin."
                              },
                              "feature": {
                                "type": "string",
                                "enum": [
                                  "LIVENESS"
                                ],
                                "description": "Fitur yang memunculkan peringatan. Selalu `LIVENESS` pada endpoint ini."
                              },
                              "additional_data": {
                                "type": "object",
                                "nullable": true,
                                "additionalProperties": true,
                                "description": "`null` untuk sebagian besar peringatan. Kecocokan daftar blokir memuat `{blocklisted_session_id, blocklisted_session_number, api_service}`; kecocokan duplikat memuat `{duplicated_session_id, duplicated_session_number, api_service}` yang mengarah ke sesi yang cocok."
                              },
                              "log_type": {
                                "type": "string",
                                "enum": [
                                  "error",
                                  "warning",
                                  "information"
                                ],
                                "description": "Tingkat keparahan. Peringatan `error` mendorong `status` menjadi `Declined`; entri `warning` dan `information` bersifat anjuran dan tidak pernah menolak dengan sendirinya."
                              },
                              "short_description": {
                                "type": "string",
                                "description": "Ringkasan satu baris yang dapat dibaca manusia tentang risiko."
                              },
                              "long_description": {
                                "type": "string",
                                "description": "Penjelasan risiko yang mudah dibaca manusia."
                              }
                            }
                          }
                        },
                        "face_quality": {
                          "type": "number",
                          "format": "float",
                          "nullable": true,
                          "minimum": 0,
                          "maximum": 100,
                          "description": "Skor kualitas pengambilan wajah yang terdeteksi, dinormalisasi ke 0–100. `null` jika model tidak dapat menghasilkan nilai yang andal.",
                          "example": 84.21
                        },
                        "face_luminance": {
                          "type": "number",
                          "format": "float",
                          "nullable": true,
                          "minimum": 0,
                          "maximum": 100,
                          "description": "Kecerahan wajah yang terdeteksi, dinormalisasi ke 0–100. `null` jika tidak tersedia.",
                          "example": 50.33
                        }
                      }
                    },
                    "vendor_data": {
                      "type": "string",
                      "nullable": true,
                      "description": "Salinan `vendor_data` yang Anda kirimkan, atau `null`."
                    },
                    "metadata": {
                      "type": "object",
                      "nullable": true,
                      "additionalProperties": true,
                      "description": "Salinan objek `metadata` yang Anda kirimkan, atau `null`."
                    },
                    "created_at": {
                      "type": "string",
                      "format": "date-time",
                      "description": "Stempel waktu ISO 8601 (UTC) saat respons dibuat, misalnya `2026-06-12T01:04:42.763237+00:00`."
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Kesalahan validasi. Dikembalikan ketika `user_image` tidak ada, melebihi 5 MB, memiliki ekstensi yang tidak didukung, gagal dalam decoding gambar di sisi server, atau ketika sebuah opsi berada di luar rentang. Kesalahan kolom menggunakan envelope `{field: [messages]}` milik DRF; kegagalan decoding gambar menggunakan `{\"error\": ...}`.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing image": {
                    "summary": "`user_image` tidak disertakan dalam data formulir",
                    "value": {
                      "user_image": [
                        "No file was submitted."
                      ]
                    }
                  },
                  "Invalid image format": {
                    "summary": "Ekstensi diizinkan tetapi konten gambar tidak dapat didekode",
                    "value": {
                      "error": "Invalid user image format.",
                      "code": "invalid_image"
                    }
                  },
                  "Unsupported file extension": {
                    "summary": "Ekstensi file di luar 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": "Unggahan melebihi batas 5 MB",
                    "value": {
                      "user_image": [
                        "File size should not exceed 5 MB"
                      ]
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Izin ditolak. Dikembalikan ketika header `x-api-key` tidak ada, dan juga ketika saldo organisasi pemanggil tidak dapat mencukupi biaya panggilan tersebut; kunci yang salah, dicabut, atau kedaluwarsa mengembalikan `401`. Kunci yang tidak ada mengembalikan `403` dengan `{\"detail\": ...}`; kunci yang salah, dicabut, atau kedaluwarsa mengembalikan `401`. Kekurangan kredit mengembalikan `403` dengan `{\"error\": ...}` sebelum pemrosesan gambar apa pun terjadi.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing or invalid API key": {
                    "summary": "Tidak ada header `x-api-key`, atau kuncinya tidak valid/dicabut",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Not enough credits": {
                    "summary": "Saldo organisasi tidak mencukupi untuk panggilan ini",
                    "value": {
                      "error": "You don't have enough credits to perform this request. Please top up at https://business.didit.me"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Batas laju terlampaui. Endpoint POST/PATCH/DELETE berbagi anggaran 300 permintaan penulisan per menit per kunci API (pembuatan transaksi dan ingesti event memiliki anggaran terpisah sebesar 600). Respons menyertakan header `X-RateLimit-Limit`, `X-RateLimit-Remaining`, `X-RateLimit-Reset`, dan `Retry-After`.",
            "content": {
              "application/json": {
                "examples": {
                  "Write rate limit exceeded": {
                    "summary": "Lebih dari 300 permintaan tulis pada menit ini",
                    "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/passive-liveness/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -F 'user_image=@./selfie.jpg' \\\n  -F 'face_liveness_score_decline_threshold=30' \\\n  -F 'save_api_request=true' \\\n  -F 'vendor_data=user-123'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.passive_liveness.check(\n    user_image=open(\"user_image.jpg\", \"rb\"),\n    face_liveness_score_decline_threshold=30.0,\n    rotate_image=False,\n    save_api_request=True,\n    vendor_data=\"user-123\",\n    metadata={\"flow\": \"withdrawal\"},\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit, { fileFromPath } from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.passiveLiveness.check({\n  user_image: await fileFromPath(\"user_image.jpg\"),\n  face_liveness_score_decline_threshold: 30.0,\n  rotate_image: false,\n  save_api_request: true,\n  vendor_data: \"user-123\",\n  metadata: { flow: \"withdrawal\" },\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.PassiveLiveness.Check(ctx, didit.PassiveLivenessCheckParams{\n\tUserImage:                         didit.FileFromPath(\"user_image.jpg\"),\n\tFaceLivenessScoreDeclineThreshold: didit.Float(30.0),\n\tRotateImage:                       didit.Bool(false),\n\tSaveAPIRequest:                    didit.Bool(true),\n\tVendorData:                        didit.String(\"user-123\"),\n\tMetadata:                          didit.Some(map[string]any{\"flow\": \"withdrawal\"}),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.nio.file.Path;\nimport java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.PassiveLivenessCheckParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.passiveLiveness().check(PassiveLivenessCheckParams.builder()\n        .userImage(Path.of(\"user_image.jpg\"))\n        .faceLivenessScoreDeclineThreshold(30.0)\n        .rotateImage(false)\n        .saveApiRequest(true)\n        .vendorData(\"user-123\")\n        .metadata(Map.of(\"flow\", \"withdrawal\"))\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\nuse Didit\\File;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->passiveLiveness->check([\n    'user_image' => File::fromPath('user_image.jpg'),\n    'face_liveness_score_decline_threshold' => 30.0,\n    'rotate_image' => false,\n    'save_api_request' => true,\n    'vendor_data' => 'user-123',\n    'metadata' => ['flow' => 'withdrawal'],\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.passive_liveness.check(\n  user_image: Pathname(\"user_image.jpg\"),\n  face_liveness_score_decline_threshold: 30.0,\n  rotate_image: false,\n  save_api_request: true,\n  vendor_data: \"user-123\",\n  metadata: { flow: \"withdrawal\" }\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.PassiveLiveness.CheckAsync(new PassiveLivenessCheckParams\n{\n    UserImage = FileUpload.FromPath(\"user_image.jpg\"),\n    FaceLivenessScoreDeclineThreshold = 30.0,\n    RotateImage = false,\n    SaveApiRequest = true,\n    VendorData = \"user-123\",\n    Metadata = new Dictionary<string, object> { [\"flow\"] = \"withdrawal\" },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/database-validation/": {
      "post": {
        "summary": "Validasi Database (mandiri)",
        "operationId": "post_v3database-validation",
        "x-didit-sdk": {
          "resource": "database_validation",
          "method": "validate",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Standalone APIs"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [],
        "description": "Validasi data identitas seseorang terhadap sumber resmi pemerintah dan registri — CPF di Brasil, RENAPER di Argentina, registri DNI di Spanyol dan Peru, INE di Meksiko, dan 100+ layanan lainnya di 60+ negara.\n\n**Pemilihan layanan.** Setiap negara mengekspos satu atau beberapa layanan katalog yang diidentifikasi oleh `service_id` (misalnya `bra_cpf`, `arg_renaper`, `pan_cedula_sib`). Tentukan layanan yang Anda inginkan dengan array `services` — jika Anda tidak menyertakannya, tepat **satu** layanan default yang akan dijalankan (layanan lingkungan produksi yang paling lama beroperasi untuk negara tersebut). Mengirimkan `services` juga mengalihkan respons ke format lanjutan dengan `services_used` dan `match_score`. Temukan layanan, kolom yang diperlukan, dan harga melalui `GET /v1/organization/database-validation-countries/` (endpoint katalog yang tidak didokumentasikan dalam spesifikasi ini) atau editor alur kerja Business Console. Beberapa layanan ditandai `requires_consent=true` dalam katalog dan memerlukan `consent=true`; layanan lainnya memerlukan onboarding untuk organisasi Anda sebelum dapat dipanggil.\n\n**Kolom input.** `identification_number` adalah kolom universal yang dipetakan ke kolom spesifik negara yang tepat secara otomatis (lihat deskripsinya). Aturan format negara diberlakukan sebelum penyedia mana pun dipanggil (misalnya CPF BRA harus tepat 11 digit) dan kegagalan format tidak pernah ditagih. Layanan biometrik memerlukan unggahan `selfie` (hanya multipart); Argentina RENAPER juga memerlukan `gender`.\n\n**Hasil.** Setiap layanan mengembalikan peta `validation` kolom per kolom ditambah `outcome_code` yang netral terhadap vendor (`MATCH`, `PARTIAL_MATCH`, `NO_MATCH`, `DOCUMENT_NOT_FOUND`, `INVALID_DOCUMENT_FORMAT`, `INVALID_INPUT`, `MINOR_BLOCKED`, `DECEASED`, `BIOMETRIC_NO_MATCH`, `BIOMETRIC_IMAGE_UNUSABLE`, `INCONCLUSIVE`, `DOCUMENT_SUPERSEDED`, `REGISTRY_UNAVAILABLE`, `REGISTRY_ERROR`). Perhatikan perbedaannya: `NO_MATCH` adalah ketidakcocokan pasti, `INCONCLUSIVE` berarti registri tidak dapat mengonfirmasi salah satunya (perlu ditinjau, bukan ditolak), dan `BIOMETRIC_IMAGE_UNUSABLE` adalah masalah swafoto teknis (ambil ulang), berbeda dengan `BIOMETRIC_NO_MATCH` yang bersifat pasti. `match_type` keseluruhan mengagregasikan di seluruh layanan (apa pun yang penuh → `full_match`, jika tidak ada dan ada yang parsial → `partial_match`, selain itu `no_match`) dan `no_match_action`/`partial_match_action` menerjemahkannya ke dalam `status` akhir. `validation_type` diturunkan: `two_by_two` ketika dua atau lebih layanan berbeda menghasilkan kecocokan penuh (pada nomor identifikasi, pada nama lengkap + tanggal lahir bersamaan, atau pada alamat tanpa kontradiksi), selain itu `one_by_one`.\n\n**Persistensi.** `save_api_request` default-nya adalah **true**: hasilnya disimpan sebagai sesi (`request_id` berfungsi dengan `GET /v3/session/{sessionId}/decision/`), muncul di konsol, dan memicu webhook `status.updated`. Parameter ini juga mengontrol format `validations` — objek per layanan saat disimpan, peta gabungan `{field: match}` saat tidak disimpan.\n\n**Penagihan.** Per-layanan: setiap layanan yang mengembalikan hasil yang dapat ditagih akan dikenakan harga katalognya masing-masing. Layanan yang gagal atau dilewati tidak ditagih, dan permintaan yang ditolak dengan `400` tidak dikenakan biaya. Pemeriksaan saldo awal mencakup jumlah harga layanan yang dipilih (`403` jika kurang).\n\n**Kegagalan.** Ketika tidak ada layanan yang dipilih mengembalikan hasil yang dapat digunakan, API mengembalikan `400` dengan `validation_errors` jika setiap upaya yang tidak terjawab secara eksplisit menolak input (`provider_rejected_input`, `retryable: false`). Perbaiki input sebelum mencoba lagi. Jika tidak, API mengembalikan `502` dengan `validation_errors` (`empty_provider_response`, `retryable: true`), termasuk penolakan input campuran dan upaya fallback yang tidak tersedia; tidak ada yang ditagih (sesi tetap dicatat dengan status `Not Finished` jika `save_api_request=true`). Ketika hanya beberapa layanan yang gagal, respons `200` menyertakan kegagalan tersebut dalam `database_validation.errors`.\n\n**Sandbox.** Kunci API dari aplikasi sandbox melewati panggilan registri dan penagihan serta mengembalikan respons `full_match` statis — payload sandbox selalu menyertakan `services_used` dan `match_score: 100` terlepas dari bagaimana `services` dikirimkan, jadi jangan memvalidasi logika pengaktifan format lanjutan di lingkungan produksi atau nilai pecahan `match_score` 0.0–1.0 terhadap respons sandbox.\n\nKirim permintaan sebagai `application/json`, atau sebagai `multipart/form-data` saat mengunggah `selfie`.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "issuing_state"
                ],
                "properties": {
                  "issuing_state": {
                    "type": "string",
                    "description": "Kode negara ISO 3166-1 **alpha-3** dari registri yang akan divalidasi (misalnya `BRA`, `ESP`, `COL`). Menentukan layanan mana yang tersedia. Kode yang tidak didukung mengembalikan `400` beserta daftar lengkap opsi yang valid.",
                    "example": "BRA"
                  },
                  "services": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "`service_id` katalog yang akan dijalankan untuk negara ini (misalnya `[\"bra_cpf\"]`). Menerima juga string tunggal atau string yang dipisahkan koma/di-encode JSON. **Jika dihilangkan atau kosong, tepat satu layanan default yang akan dijalankan** — layanan aktif yang paling lama tersedia untuk negara tersebut; layanan yang lebih baru, biometrik, dan bayar sesuai penggunaan harus disebutkan secara eksplisit. Mengirim `services` akan mengubah bentuk respons ke format yang diperluas (menambahkan `services_used` dan `match_score`). Setiap id harus ada dan aktif untuk `issuing_state`; layanan yang memerlukan onboarding mengembalikan `400` sampai diaktifkan untuk organisasi Anda. Temukan layanan yang tersedia per negara melalui `GET /v1/organization/database-validation-countries/` (endpoint katalog yang tidak didokumentasikan dalam spesifikasi ini) atau editor alur kerja Business Console.",
                    "example": [
                      "bra_cpf"
                    ]
                  },
                  "validation_type": {
                    "type": "string",
                    "deprecated": true,
                    "description": "USANG. Diterima untuk kompatibilitas mundur tetapi diabaikan — `validation_type` respons sekarang diturunkan dari berapa banyak layanan yang cocok penuh. Gunakan `services` untuk menetapkan layanan tertentu."
                  },
                  "consent": {
                    "type": "boolean",
                    "default": false,
                    "description": "Atur ke `true` jika pengguna akhir telah memberikan persetujuan secara eksplisit untuk layanan validasi yang dipilih. Diperlukan untuk layanan yang ditandai `requires_consent=true` di katalog — tanpanya, layanan tersebut mengembalikan `400` dengan `services_requiring_consent`."
                  },
                  "identification_number": {
                    "type": "string",
                    "description": "Nomor identifikasi universal — dipetakan secara otomatis ke kolom spesifik negara yang tepat, sehingga Anda dapat menggunakannya alih-alih `personal_number`/`tax_number`/`document_number`: ARG→document_number (DNI), BOL→document_number (CI), BRA→tax_number (CPF, 11 digit), CHL→personal_number (RUT), COL→personal_number (Cédula), CRI→personal_number (Cédula), DOM→personal_number (Cédula, 11 digit), ECU→personal_number (Cédula, 10 digit), ESP→personal_number (DNI/NIE), GTM→document_number (DPI), HND→document_number (DNI), MEX→personal_number (CURP, 18 karakter), PAN→personal_number (Cédula), PER→personal_number (DNI, 8 digit), PRY→document_number (CI), SLV→document_number (DUI), URY→personal_number (CI), VEN→document_number (Cédula). Nilai ini tidak pernah menimpa kolom spesifik negara yang diberikan secara eksplisit."
                  },
                  "first_name": {
                    "type": "string",
                    "description": "Nama depan individu. Diperlukan oleh beberapa layanan/negara.",
                    "example": "John"
                  },
                  "last_name": {
                    "type": "string",
                    "description": "Nama belakang individu. Diperlukan oleh beberapa layanan/negara.",
                    "example": "Doe"
                  },
                  "middle_name": {
                    "type": "string",
                    "description": "Nama tengah, digunakan oleh beberapa layanan negara (AUS, NZL, …)."
                  },
                  "full_name": {
                    "type": "string",
                    "description": "Nama lengkap — beberapa layanan menerima ini sebagai pengganti nama depan/belakang (misalnya layanan CHN, yang mencocokkan nama dalam aksara asli)."
                  },
                  "date_of_birth": {
                    "type": "string",
                    "format": "date",
                    "description": "Tanggal lahir, `YYYY-MM-DD`. Diperlukan oleh banyak layanan.",
                    "example": "1980-01-01"
                  },
                  "personal_number": {
                    "type": "string",
                    "description": "Pengenal pribadi unik yang diterbitkan pemerintah. Digunakan oleh: CHL (RUT), COL (Cédula), CRI, DOM, ECU, ESP (DNI/NIE), MEX (CURP), PAN (Cédula), PER (DNI), URY. Pertimbangkan untuk menggunakan `identification_number` sebagai gantinya."
                  },
                  "tax_number": {
                    "type": "string",
                    "description": "ID pajak. Digunakan oleh: BRA (CPF, 11 digit). Pertimbangkan untuk menggunakan `identification_number` sebagai gantinya."
                  },
                  "document_number": {
                    "type": "string",
                    "description": "Nomor dokumen. Digunakan oleh: ARG (DNI), BOL (CI), GTM (DPI), HND (DNI), PRY (CI), SLV (DUI), VEN (Cédula). Pertimbangkan untuk menggunakan `identification_number` sebagai gantinya."
                  },
                  "document_type": {
                    "type": "string",
                    "enum": [
                      "P",
                      "DL",
                      "ID",
                      "RP",
                      "SSC",
                      "HIC",
                      "WP",
                      "TC",
                      "VISA",
                      "PSC",
                      "BC",
                      "OTHER"
                    ],
                    "description": "Jenis dokumen yang divalidasi: paspor `P`, SIM `DL`, ID nasional `ID`, izin tinggal `RP` (ditambah `SSC`, `HIC`, `WP`, `TC`, `VISA`, `PSC`, `BC`, `OTHER`). Diperlukan oleh beberapa layanan (misalnya ESP)."
                  },
                  "expiration_date": {
                    "type": "string",
                    "format": "date",
                    "description": "Tanggal kedaluwarsa dokumen, `YYYY-MM-DD`. Wajib untuk validasi ESP (Spanyol).",
                    "example": "2030-01-15"
                  },
                  "date_of_issue": {
                    "type": "string",
                    "format": "date",
                    "description": "Tanggal penerbitan dokumen, `YYYY-MM-DD` (fecha de expedición). Wajib untuk validasi cédula COL (Kolombia).",
                    "example": "2015-06-20"
                  },
                  "nationality": {
                    "type": "string",
                    "description": "Kewarganegaraan sebagai ISO 3166-1 alpha-3. Diperlukan oleh beberapa layanan."
                  },
                  "gender": {
                    "type": "string",
                    "enum": [
                      "M",
                      "F",
                      "X"
                    ],
                    "description": "Jenis kelamin: `M`, `F`, atau `X` (lainnya/tidak diketahui). Diperlukan untuk validasi RENAPER Argentina (`arg_renaper`)."
                  },
                  "address": {
                    "description": "Alamat tempat tinggal. Utamakan objek terstruktur `{\"street_1\":\"123 Main St\",\"street_2\":\"Apt 4B\",\"city\":\"Springfield\",\"region\":\"IL\",\"postal_code\":\"62701\",\"country\":\"US\"}`; string satu baris lengkap masih diterima. Diperlukan oleh layanan verifikasi alamat; jika suatu layanan menentukan persyaratan alamat, bagian yang hilang akan mengembalikan `400` dengan `address_fields_required_by`.",
                    "oneOf": [
                      {
                        "type": "object",
                        "properties": {
                          "street_1": {
                            "type": "string"
                          },
                          "street_2": {
                            "type": "string"
                          },
                          "city": {
                            "type": "string"
                          },
                          "region": {
                            "type": "string"
                          },
                          "postal_code": {
                            "type": "string"
                          },
                          "country": {
                            "type": "string"
                          }
                        }
                      },
                      {
                        "type": "string",
                        "description": "Alamat satu baris lengkap (lama)."
                      }
                    ]
                  },
                  "address_element_1": {
                    "type": "string",
                    "description": "Alamat jalan termasuk nomor jalan dan jenis jalan. Jika dihilangkan, diturunkan dari `address`."
                  },
                  "address_element_2": {
                    "type": "string",
                    "description": "Apartemen, unit, gedung, lantai, atau baris alamat tambahan. Kirimkan hanya jika Anda memilikinya secara eksplisit."
                  },
                  "address_element_3": {
                    "type": "string",
                    "description": "Kota, pinggiran kota, distrik, lokalitas, atau lingkungan. Jika dihilangkan, diturunkan dari `address`."
                  },
                  "address_element_4": {
                    "type": "string",
                    "description": "Negara bagian, provinsi, wilayah, atau kota. Jika dihilangkan, diambil dari `address`."
                  },
                  "address_element_5": {
                    "type": "string",
                    "description": "Kode pos. `postal_code` diterima sebagai alias."
                  },
                  "postal_code": {
                    "type": "string",
                    "description": "Kode pos untuk layanan berbasis alamat (alias dari `address_element_5`)."
                  },
                  "driver_license_number": {
                    "type": "string",
                    "description": "Nomor surat izin mengemudi untuk layanan verifikasi dokumen pemerintah (AUS, NZL, IND)."
                  },
                  "driver_license_card_number": {
                    "type": "string",
                    "description": "Nomor kartu fisik surat izin mengemudi, jika diwajibkan secara terpisah dari nomor lisensi (AUS)."
                  },
                  "driver_license_state": {
                    "type": "string",
                    "description": "Negara bagian atau wilayah penerbitan surat izin mengemudi (AUS)."
                  },
                  "driver_license_version": {
                    "type": "string",
                    "description": "Kode versi surat izin mengemudi (NZL)."
                  },
                  "passport_number": {
                    "type": "string",
                    "description": "Nomor paspor untuk layanan verifikasi paspor pemerintah (AUS, NZL, IND, CHN)."
                  },
                  "passport_expiration_date": {
                    "type": "string",
                    "format": "date",
                    "description": "Tanggal kedaluwarsa paspor, `YYYY-MM-DD`, untuk layanan verifikasi paspor."
                  },
                  "passport_file_number": {
                    "type": "string",
                    "description": "Nomor berkas paspor (IND)."
                  },
                  "passport_issue_country": {
                    "type": "string",
                    "description": "Negara penerbit paspor (ISO 3166-1 alpha-3) untuk layanan verifikasi paspor."
                  },
                  "medicare_card_number": {
                    "type": "string",
                    "description": "Nomor kartu Medicare (AUS)."
                  },
                  "immi_card_number": {
                    "type": "string",
                    "description": "Nomor ImmiCard Australia."
                  },
                  "immi_card_expiry_date": {
                    "type": "string",
                    "format": "date",
                    "description": "Tanggal kedaluwarsa ImmiCard Australia."
                  },
                  "citizenship_certificate_number": {
                    "type": "string",
                    "description": "Nomor sertifikat kewarganegaraan (AUS)."
                  },
                  "birth_registration_number": {
                    "type": "string",
                    "description": "Nomor registrasi akta kelahiran (AUS)."
                  },
                  "birth_registration_date": {
                    "type": "string",
                    "format": "date",
                    "description": "Tanggal pendaftaran akta kelahiran (AUS)."
                  },
                  "birth_registration_state": {
                    "type": "string",
                    "description": "Negara bagian pendaftaran akta kelahiran (AUS)."
                  },
                  "marriage_certificate_number": {
                    "type": "string",
                    "description": "Nomor akta nikah (AUS)."
                  },
                  "change_of_name_certificate_number": {
                    "type": "string",
                    "description": "Nomor sertifikat perubahan nama (AUS)."
                  },
                  "first_partner_name": {
                    "type": "string",
                    "description": "Nama depan pasangan pada surat nikah (AUS)."
                  },
                  "last_partner_name": {
                    "type": "string",
                    "description": "Nama belakang pasangan pada surat nikah (AUS)."
                  },
                  "voter_id": {
                    "type": "string",
                    "description": "Nomor pendaftaran pemilih (IND EPIC, IRL)."
                  },
                  "epic_card": {
                    "type": "string",
                    "description": "Nomor kartu pemilih EPIC India."
                  },
                  "pan": {
                    "type": "string",
                    "description": "PAN (Permanent Account Number) India."
                  },
                  "national_id": {
                    "type": "string",
                    "description": "Nomor identitas nasional (CHN, MYS, KEN, KHM, NGA, ZAF, …)."
                  },
                  "cic": {
                    "type": "string",
                    "description": "Código de Identificación de Credencial (CIC) INE/IFE Meksiko, 9 digit. Digunakan oleh layanan validitas kredensial MEX INE (`mex_ine_vigencia`)."
                  },
                  "identificador_ciudadano": {
                    "type": "string",
                    "description": "INE Identificador del Ciudadano Meksiko (9 digit). Digunakan bersama `cic` untuk model INE modern (E/F/G/H) dalam `mex_ine_vigencia`."
                  },
                  "ocr": {
                    "type": "string",
                    "description": "Nomor OCR INE Meksiko (13 digit, bagian belakang kartu). Digunakan bersama `cic` untuk Model D dalam `mex_ine_vigencia`."
                  },
                  "voter_number": {
                    "type": "string",
                    "description": "INE Clave de Elector Meksiko (18 karakter). Digunakan bersama `emission_number` untuk model IFE lawas (A/B/C) dalam `mex_ine_vigencia`."
                  },
                  "emission_number": {
                    "type": "string",
                    "description": "INE Número de Emisión Meksiko. Digunakan bersama `voter_number` untuk model IFE lawas (A/B/C) dalam `mex_ine_vigencia`."
                  },
                  "bvn": {
                    "type": "string",
                    "description": "Nomor Verifikasi Bank Nigeria."
                  },
                  "bank_card_number": {
                    "type": "string",
                    "description": "Nomor kartu bank (verifikasi kartu bank CHN)."
                  },
                  "company_registration_number": {
                    "type": "string",
                    "description": "Nomor registrasi perusahaan sebagaimana diterbitkan oleh registri perusahaan: CNPJ di Brasil (mis. `11222333000181`), nomor registrasi di Afrika Selatan (mis. `1936/007721/06`). Diperlukan oleh layanan registri perusahaan dan direktur perusahaan (`bra_company_registry`, `bra_company_directors`, `zaf_company_registry`, `zaf_company_directors`)."
                  },
                  "company_name": {
                    "type": "string",
                    "description": "Nama perusahaan terdaftar, diperiksa silang terhadap entri registri. Opsional untuk `zaf_company_registry`."
                  },
                  "initials": {
                    "type": "string",
                    "description": "Inisial orang tersebut seperti yang tertera pada dokumen. Wajib untuk `zaf_drivers_license`; diterima untuk `zaf_bank_account_holder`."
                  },
                  "licence_number": {
                    "type": "string",
                    "description": "Nomor surat izin mengemudi seperti yang tertera pada kartu, untuk `zaf_drivers_license`. Jika dihilangkan, `document_number` yang digunakan."
                  },
                  "refugee_file_number": {
                    "type": "string",
                    "description": "Nomor berkas pengungsi yang diterbitkan oleh Departemen Dalam Negeri Afrika Selatan. Wajib untuk `zaf_refugee`."
                  },
                  "bank_name": {
                    "type": "string",
                    "description": "Nama bank pemegang rekening. Wajib untuk `zaf_bank_account_holder`."
                  },
                  "bank_account_number": {
                    "type": "string",
                    "description": "Nomor rekening bank. Wajib untuk `zaf_bank_account_holder`; diterima oleh `zaf_fraud_prevention`."
                  },
                  "account_type": {
                    "type": "string",
                    "description": "Jenis rekening bank untuk `zaf_bank_account_holder`: `current`, `savings`, `transmission`, `subscriptionShare`, atau `notKnown`, tidak peka huruf besar/kecil. Nilai lain apa pun mengembalikan `400`. Abaikan jika Anda tidak mengetahui jenisnya: pemeriksaan silang jenis rekening kemudian dilaporkan sebagai tidak terkonfirmasi."
                  },
                  "phone_number": {
                    "type": "string",
                    "description": "Nomor ponsel kontak, untuk layanan yang memeriksa ulang keterjangkauan kontak (`zaf_bank_account_holder`, `zaf_fraud_prevention`, `zaf_refugee`)."
                  },
                  "right_thumb": {
                    "type": "string",
                    "description": "Sidik jari jempol kanan yang di-encode Base64 untuk `zaf_dha_fingerprint_match`, bersama `left_thumb` atau secara terpisah."
                  },
                  "left_thumb": {
                    "type": "string",
                    "description": "Sidik jari jempol kiri yang di-encode Base64 untuk `zaf_dha_fingerprint_match`, bersama `right_thumb` atau secara terpisah."
                  },
                  "score_level": {
                    "type": "integer",
                    "description": "Tingkat skor biometrik minimum untuk `zaf_criminal_face_screening`. Defaultnya adalah `3`."
                  },
                  "max_matches": {
                    "type": "integer",
                    "description": "Jumlah maksimum kandidat kecocokan yang dikembalikan oleh `zaf_criminal_face_screening`. Defaultnya adalah `1`."
                  },
                  "vehicle_register_number": {
                    "type": "string",
                    "description": "Nomor registrasi kendaraan. Wajib diisi, bersama dengan `vehicle_licence_plate` dan `vin`, oleh `zaf_vehicle_ownership`."
                  },
                  "vehicle_licence_plate": {
                    "type": "string",
                    "description": "Nomor plat kendaraan. Wajib diisi, bersama dengan `vehicle_register_number` dan `vin`, oleh `zaf_vehicle_ownership`."
                  },
                  "vin": {
                    "type": "string",
                    "description": "Nomor Identifikasi Kendaraan (VIN atau nomor rangka). Wajib diisi, bersama dengan `vehicle_register_number` dan `vehicle_licence_plate`, oleh `zaf_vehicle_ownership`."
                  },
                  "ssn": {
                    "type": "string",
                    "description": "Social Security Number (AS)."
                  },
                  "phone": {
                    "type": "string",
                    "description": "Nomor telepon untuk layanan verifikasi telepon."
                  },
                  "landline": {
                    "type": "string",
                    "description": "Nomor telepon rumah untuk layanan verifikasi telepon."
                  },
                  "email": {
                    "type": "string",
                    "format": "email",
                    "description": "Alamat email untuk layanan verifikasi identitas."
                  },
                  "country_of_residence": {
                    "type": "string",
                    "description": "Negara tempat tinggal ISO 3166-1 alpha-2. Digunakan oleh layanan pengayaan identitas global (misalnya `glb_identity_enrichment`) untuk memfokuskan pencarian.",
                    "example": "US"
                  },
                  "partial_match_action": {
                    "type": "string",
                    "enum": [
                      "DECLINE",
                      "NO_ACTION"
                    ],
                    "default": "NO_ACTION",
                    "description": "Pengaruh `partial_match` terhadap `database_validation.status`. Default ke `NO_ACTION` (status tetap `Approved`, dengan peringatan)."
                  },
                  "no_match_action": {
                    "type": "string",
                    "enum": [
                      "DECLINE",
                      "NO_ACTION"
                    ],
                    "default": "DECLINE",
                    "description": "Pengaruh `no_match` terhadap `database_validation.status`. Default ke `DECLINE`."
                  },
                  "save_api_request": {
                    "type": "boolean",
                    "default": true,
                    "description": "Simpan validasi sebagai sesi (visibilitas konsol, endpoint keputusan, webhook `status.updated`). Tindakan ini juga mengubah bentuk respons `validations`: objek per layanan saat `true` (default), peta kolom gabungan saat `false`."
                  },
                  "vendor_data": {
                    "type": "string",
                    "description": "Pengenal Anda untuk pengguna yang divalidasi; dikembalikan dan disimpan bersama sesi."
                  },
                  "metadata": {
                    "type": "object",
                    "nullable": true,
                    "description": "JSON bentuk bebas yang disimpan bersama permintaan dan dikembalikan dalam respons."
                  }
                }
              },
              "example": {
                "issuing_state": "BRA",
                "services": [
                  "bra_cpf"
                ],
                "identification_number": "12345678900",
                "first_name": "John",
                "last_name": "Doe",
                "date_of_birth": "1980-01-01",
                "vendor_data": "user-1234"
              }
            },
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "required": [
                  "issuing_state"
                ],
                "properties": {
                  "issuing_state": {
                    "type": "string",
                    "description": "Kode negara ISO 3166-1 **alpha-3** dari registri yang akan divalidasi (misalnya `BRA`, `ESP`, `COL`). Menentukan layanan mana yang tersedia. Kode yang tidak didukung mengembalikan `400` beserta daftar lengkap opsi yang valid.",
                    "example": "BRA"
                  },
                  "services": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "`service_id` katalog yang akan dijalankan untuk negara ini (misalnya `[\"bra_cpf\"]`). Menerima juga string tunggal atau string yang dipisahkan koma/di-encode JSON. **Jika dihilangkan atau kosong, tepat satu layanan default yang akan dijalankan** — layanan aktif yang paling lama tersedia untuk negara tersebut; layanan yang lebih baru, biometrik, dan bayar sesuai penggunaan harus disebutkan secara eksplisit. Mengirim `services` akan mengubah bentuk respons ke format yang diperluas (menambahkan `services_used` dan `match_score`). Setiap id harus ada dan aktif untuk `issuing_state`; layanan yang memerlukan onboarding mengembalikan `400` sampai diaktifkan untuk organisasi Anda. Temukan layanan yang tersedia per negara melalui `GET /v1/organization/database-validation-countries/` (endpoint katalog yang tidak didokumentasikan dalam spesifikasi ini) atau editor alur kerja Business Console.",
                    "example": [
                      "bra_cpf"
                    ]
                  },
                  "validation_type": {
                    "type": "string",
                    "deprecated": true,
                    "description": "USANG. Diterima untuk kompatibilitas mundur tetapi diabaikan — `validation_type` respons sekarang diturunkan dari berapa banyak layanan yang cocok penuh. Gunakan `services` untuk menetapkan layanan tertentu."
                  },
                  "consent": {
                    "type": "boolean",
                    "default": false,
                    "description": "Atur ke `true` jika pengguna akhir telah memberikan persetujuan secara eksplisit untuk layanan validasi yang dipilih. Diperlukan untuk layanan yang ditandai `requires_consent=true` di katalog — tanpanya, layanan tersebut mengembalikan `400` dengan `services_requiring_consent`."
                  },
                  "identification_number": {
                    "type": "string",
                    "description": "Nomor identifikasi universal — dipetakan secara otomatis ke kolom spesifik negara yang tepat, sehingga Anda dapat menggunakannya alih-alih `personal_number`/`tax_number`/`document_number`: ARG→document_number (DNI), BOL→document_number (CI), BRA→tax_number (CPF, 11 digit), CHL→personal_number (RUT), COL→personal_number (Cédula), CRI→personal_number (Cédula), DOM→personal_number (Cédula, 11 digit), ECU→personal_number (Cédula, 10 digit), ESP→personal_number (DNI/NIE), GTM→document_number (DPI), HND→document_number (DNI), MEX→personal_number (CURP, 18 karakter), PAN→personal_number (Cédula), PER→personal_number (DNI, 8 digit), PRY→document_number (CI), SLV→document_number (DUI), URY→personal_number (CI), VEN→document_number (Cédula). Nilai ini tidak pernah menimpa kolom spesifik negara yang diberikan secara eksplisit."
                  },
                  "first_name": {
                    "type": "string",
                    "description": "Nama depan individu. Diperlukan oleh beberapa layanan/negara.",
                    "example": "John"
                  },
                  "last_name": {
                    "type": "string",
                    "description": "Nama belakang individu. Diperlukan oleh beberapa layanan/negara.",
                    "example": "Doe"
                  },
                  "middle_name": {
                    "type": "string",
                    "description": "Nama tengah, digunakan oleh beberapa layanan negara (AUS, NZL, …)."
                  },
                  "full_name": {
                    "type": "string",
                    "description": "Nama lengkap — beberapa layanan menerima ini sebagai pengganti nama depan/belakang (misalnya layanan CHN, yang mencocokkan nama dalam aksara asli)."
                  },
                  "date_of_birth": {
                    "type": "string",
                    "format": "date",
                    "description": "Tanggal lahir, `YYYY-MM-DD`. Diperlukan oleh banyak layanan.",
                    "example": "1980-01-01"
                  },
                  "personal_number": {
                    "type": "string",
                    "description": "Pengenal pribadi unik yang diterbitkan pemerintah. Digunakan oleh: CHL (RUT), COL (Cédula), CRI, DOM, ECU, ESP (DNI/NIE), MEX (CURP), PAN (Cédula), PER (DNI), URY. Pertimbangkan untuk menggunakan `identification_number` sebagai gantinya."
                  },
                  "tax_number": {
                    "type": "string",
                    "description": "ID pajak. Digunakan oleh: BRA (CPF, 11 digit). Pertimbangkan untuk menggunakan `identification_number` sebagai gantinya."
                  },
                  "document_number": {
                    "type": "string",
                    "description": "Nomor dokumen. Digunakan oleh: ARG (DNI), BOL (CI), GTM (DPI), HND (DNI), PRY (CI), SLV (DUI), VEN (Cédula). Pertimbangkan untuk menggunakan `identification_number` sebagai gantinya."
                  },
                  "document_type": {
                    "type": "string",
                    "enum": [
                      "P",
                      "DL",
                      "ID",
                      "RP",
                      "SSC",
                      "HIC",
                      "WP",
                      "TC",
                      "VISA",
                      "PSC",
                      "BC",
                      "OTHER"
                    ],
                    "description": "Jenis dokumen yang divalidasi: paspor `P`, SIM `DL`, ID nasional `ID`, izin tinggal `RP` (ditambah `SSC`, `HIC`, `WP`, `TC`, `VISA`, `PSC`, `BC`, `OTHER`). Diperlukan oleh beberapa layanan (misalnya ESP)."
                  },
                  "expiration_date": {
                    "type": "string",
                    "format": "date",
                    "description": "Tanggal kedaluwarsa dokumen, `YYYY-MM-DD`. Wajib untuk validasi ESP (Spanyol).",
                    "example": "2030-01-15"
                  },
                  "date_of_issue": {
                    "type": "string",
                    "format": "date",
                    "description": "Tanggal penerbitan dokumen, `YYYY-MM-DD` (fecha de expedición). Wajib untuk validasi cédula COL (Kolombia).",
                    "example": "2015-06-20"
                  },
                  "nationality": {
                    "type": "string",
                    "description": "Kewarganegaraan sebagai ISO 3166-1 alpha-3. Diperlukan oleh beberapa layanan."
                  },
                  "gender": {
                    "type": "string",
                    "enum": [
                      "M",
                      "F",
                      "X"
                    ],
                    "description": "Jenis kelamin: `M`, `F`, atau `X` (lainnya/tidak diketahui). Diperlukan untuk validasi RENAPER Argentina (`arg_renaper`)."
                  },
                  "address": {
                    "description": "Alamat tempat tinggal. Utamakan objek terstruktur `{\"street_1\":\"123 Main St\",\"street_2\":\"Apt 4B\",\"city\":\"Springfield\",\"region\":\"IL\",\"postal_code\":\"62701\",\"country\":\"US\"}`; string satu baris lengkap masih diterima. Diperlukan oleh layanan verifikasi alamat; jika suatu layanan menentukan persyaratan alamat, bagian yang hilang akan mengembalikan `400` dengan `address_fields_required_by`.",
                    "oneOf": [
                      {
                        "type": "object",
                        "properties": {
                          "street_1": {
                            "type": "string"
                          },
                          "street_2": {
                            "type": "string"
                          },
                          "city": {
                            "type": "string"
                          },
                          "region": {
                            "type": "string"
                          },
                          "postal_code": {
                            "type": "string"
                          },
                          "country": {
                            "type": "string"
                          }
                        }
                      },
                      {
                        "type": "string",
                        "description": "Alamat satu baris lengkap (lama)."
                      }
                    ]
                  },
                  "address_element_1": {
                    "type": "string",
                    "description": "Alamat jalan termasuk nomor jalan dan jenis jalan. Jika dihilangkan, diturunkan dari `address`."
                  },
                  "address_element_2": {
                    "type": "string",
                    "description": "Apartemen, unit, gedung, lantai, atau baris alamat tambahan. Kirimkan hanya jika Anda memilikinya secara eksplisit."
                  },
                  "address_element_3": {
                    "type": "string",
                    "description": "Kota, pinggiran kota, distrik, lokalitas, atau lingkungan. Jika dihilangkan, diturunkan dari `address`."
                  },
                  "address_element_4": {
                    "type": "string",
                    "description": "Negara bagian, provinsi, wilayah, atau kota. Jika dihilangkan, diambil dari `address`."
                  },
                  "address_element_5": {
                    "type": "string",
                    "description": "Kode pos. `postal_code` diterima sebagai alias."
                  },
                  "postal_code": {
                    "type": "string",
                    "description": "Kode pos untuk layanan berbasis alamat (alias dari `address_element_5`)."
                  },
                  "driver_license_number": {
                    "type": "string",
                    "description": "Nomor surat izin mengemudi untuk layanan verifikasi dokumen pemerintah (AUS, NZL, IND)."
                  },
                  "driver_license_card_number": {
                    "type": "string",
                    "description": "Nomor kartu fisik surat izin mengemudi, jika diwajibkan secara terpisah dari nomor lisensi (AUS)."
                  },
                  "driver_license_state": {
                    "type": "string",
                    "description": "Negara bagian atau wilayah penerbitan surat izin mengemudi (AUS)."
                  },
                  "driver_license_version": {
                    "type": "string",
                    "description": "Kode versi surat izin mengemudi (NZL)."
                  },
                  "passport_number": {
                    "type": "string",
                    "description": "Nomor paspor untuk layanan verifikasi paspor pemerintah (AUS, NZL, IND, CHN)."
                  },
                  "passport_expiration_date": {
                    "type": "string",
                    "format": "date",
                    "description": "Tanggal kedaluwarsa paspor, `YYYY-MM-DD`, untuk layanan verifikasi paspor."
                  },
                  "passport_file_number": {
                    "type": "string",
                    "description": "Nomor berkas paspor (IND)."
                  },
                  "passport_issue_country": {
                    "type": "string",
                    "description": "Negara penerbit paspor (ISO 3166-1 alpha-3) untuk layanan verifikasi paspor."
                  },
                  "medicare_card_number": {
                    "type": "string",
                    "description": "Nomor kartu Medicare (AUS)."
                  },
                  "immi_card_number": {
                    "type": "string",
                    "description": "Nomor ImmiCard Australia."
                  },
                  "immi_card_expiry_date": {
                    "type": "string",
                    "format": "date",
                    "description": "Tanggal kedaluwarsa ImmiCard Australia."
                  },
                  "citizenship_certificate_number": {
                    "type": "string",
                    "description": "Nomor sertifikat kewarganegaraan (AUS)."
                  },
                  "birth_registration_number": {
                    "type": "string",
                    "description": "Nomor registrasi akta kelahiran (AUS)."
                  },
                  "birth_registration_date": {
                    "type": "string",
                    "format": "date",
                    "description": "Tanggal pendaftaran akta kelahiran (AUS)."
                  },
                  "birth_registration_state": {
                    "type": "string",
                    "description": "Negara bagian pendaftaran akta kelahiran (AUS)."
                  },
                  "marriage_certificate_number": {
                    "type": "string",
                    "description": "Nomor akta nikah (AUS)."
                  },
                  "change_of_name_certificate_number": {
                    "type": "string",
                    "description": "Nomor sertifikat perubahan nama (AUS)."
                  },
                  "first_partner_name": {
                    "type": "string",
                    "description": "Nama depan pasangan pada surat nikah (AUS)."
                  },
                  "last_partner_name": {
                    "type": "string",
                    "description": "Nama belakang pasangan pada surat nikah (AUS)."
                  },
                  "voter_id": {
                    "type": "string",
                    "description": "Nomor pendaftaran pemilih (IND EPIC, IRL)."
                  },
                  "epic_card": {
                    "type": "string",
                    "description": "Nomor kartu pemilih EPIC India."
                  },
                  "pan": {
                    "type": "string",
                    "description": "PAN (Permanent Account Number) India."
                  },
                  "national_id": {
                    "type": "string",
                    "description": "Nomor identitas nasional (CHN, MYS, KEN, KHM, NGA, ZAF, …)."
                  },
                  "cic": {
                    "type": "string",
                    "description": "Código de Identificación de Credencial (CIC) INE/IFE Meksiko, 9 digit. Digunakan oleh layanan validitas kredensial MEX INE (`mex_ine_vigencia`)."
                  },
                  "identificador_ciudadano": {
                    "type": "string",
                    "description": "INE Identificador del Ciudadano Meksiko (9 digit). Digunakan bersama `cic` untuk model INE modern (E/F/G/H) dalam `mex_ine_vigencia`."
                  },
                  "ocr": {
                    "type": "string",
                    "description": "Nomor OCR INE Meksiko (13 digit, bagian belakang kartu). Digunakan bersama `cic` untuk Model D dalam `mex_ine_vigencia`."
                  },
                  "voter_number": {
                    "type": "string",
                    "description": "INE Clave de Elector Meksiko (18 karakter). Digunakan bersama `emission_number` untuk model IFE lawas (A/B/C) dalam `mex_ine_vigencia`."
                  },
                  "emission_number": {
                    "type": "string",
                    "description": "INE Número de Emisión Meksiko. Digunakan bersama `voter_number` untuk model IFE lawas (A/B/C) dalam `mex_ine_vigencia`."
                  },
                  "bvn": {
                    "type": "string",
                    "description": "Nomor Verifikasi Bank Nigeria."
                  },
                  "bank_card_number": {
                    "type": "string",
                    "description": "Nomor kartu bank (verifikasi kartu bank CHN)."
                  },
                  "company_registration_number": {
                    "type": "string",
                    "description": "Nomor registrasi perusahaan sebagaimana diterbitkan oleh registri perusahaan: CNPJ di Brasil (mis. `11222333000181`), nomor registrasi di Afrika Selatan (mis. `1936/007721/06`). Diperlukan oleh layanan registri perusahaan dan direktur perusahaan (`bra_company_registry`, `bra_company_directors`, `zaf_company_registry`, `zaf_company_directors`)."
                  },
                  "company_name": {
                    "type": "string",
                    "description": "Nama perusahaan terdaftar, diperiksa silang terhadap entri registri. Opsional untuk `zaf_company_registry`."
                  },
                  "initials": {
                    "type": "string",
                    "description": "Inisial orang tersebut seperti yang tertera pada dokumen. Wajib untuk `zaf_drivers_license`; diterima untuk `zaf_bank_account_holder`."
                  },
                  "licence_number": {
                    "type": "string",
                    "description": "Nomor surat izin mengemudi seperti yang tertera pada kartu, untuk `zaf_drivers_license`. Jika dihilangkan, `document_number` yang digunakan."
                  },
                  "refugee_file_number": {
                    "type": "string",
                    "description": "Nomor berkas pengungsi yang diterbitkan oleh Departemen Dalam Negeri Afrika Selatan. Wajib untuk `zaf_refugee`."
                  },
                  "bank_name": {
                    "type": "string",
                    "description": "Nama bank pemegang rekening. Wajib untuk `zaf_bank_account_holder`."
                  },
                  "bank_account_number": {
                    "type": "string",
                    "description": "Nomor rekening bank. Wajib untuk `zaf_bank_account_holder`; diterima oleh `zaf_fraud_prevention`."
                  },
                  "account_type": {
                    "type": "string",
                    "description": "Jenis rekening bank untuk `zaf_bank_account_holder`: `current`, `savings`, `transmission`, `subscriptionShare`, atau `notKnown`, tidak peka huruf besar/kecil. Nilai lain apa pun mengembalikan `400`. Abaikan jika Anda tidak mengetahui jenisnya: pemeriksaan silang jenis rekening kemudian dilaporkan sebagai tidak terkonfirmasi."
                  },
                  "phone_number": {
                    "type": "string",
                    "description": "Nomor ponsel kontak, untuk layanan yang memeriksa ulang keterjangkauan kontak (`zaf_bank_account_holder`, `zaf_fraud_prevention`, `zaf_refugee`)."
                  },
                  "right_thumb": {
                    "type": "string",
                    "description": "Sidik jari jempol kanan yang di-encode Base64 untuk `zaf_dha_fingerprint_match`, bersama `left_thumb` atau secara terpisah."
                  },
                  "left_thumb": {
                    "type": "string",
                    "description": "Sidik jari jempol kiri yang di-encode Base64 untuk `zaf_dha_fingerprint_match`, bersama `right_thumb` atau secara terpisah."
                  },
                  "score_level": {
                    "type": "integer",
                    "description": "Tingkat skor biometrik minimum untuk `zaf_criminal_face_screening`. Defaultnya adalah `3`."
                  },
                  "max_matches": {
                    "type": "integer",
                    "description": "Jumlah maksimum kandidat kecocokan yang dikembalikan oleh `zaf_criminal_face_screening`. Defaultnya adalah `1`."
                  },
                  "vehicle_register_number": {
                    "type": "string",
                    "description": "Nomor registrasi kendaraan. Wajib diisi, bersama dengan `vehicle_licence_plate` dan `vin`, oleh `zaf_vehicle_ownership`."
                  },
                  "vehicle_licence_plate": {
                    "type": "string",
                    "description": "Nomor plat kendaraan. Wajib diisi, bersama dengan `vehicle_register_number` dan `vin`, oleh `zaf_vehicle_ownership`."
                  },
                  "vin": {
                    "type": "string",
                    "description": "Nomor Identifikasi Kendaraan (VIN atau nomor rangka). Wajib diisi, bersama dengan `vehicle_register_number` dan `vehicle_licence_plate`, oleh `zaf_vehicle_ownership`."
                  },
                  "ssn": {
                    "type": "string",
                    "description": "Social Security Number (AS)."
                  },
                  "phone": {
                    "type": "string",
                    "description": "Nomor telepon untuk layanan verifikasi telepon."
                  },
                  "landline": {
                    "type": "string",
                    "description": "Nomor telepon rumah untuk layanan verifikasi telepon."
                  },
                  "email": {
                    "type": "string",
                    "format": "email",
                    "description": "Alamat email untuk layanan verifikasi identitas."
                  },
                  "country_of_residence": {
                    "type": "string",
                    "description": "Negara tempat tinggal ISO 3166-1 alpha-2. Digunakan oleh layanan pengayaan identitas global (misalnya `glb_identity_enrichment`) untuk memfokuskan pencarian.",
                    "example": "US"
                  },
                  "partial_match_action": {
                    "type": "string",
                    "enum": [
                      "DECLINE",
                      "NO_ACTION"
                    ],
                    "default": "NO_ACTION",
                    "description": "Pengaruh `partial_match` terhadap `database_validation.status`. Default ke `NO_ACTION` (status tetap `Approved`, dengan peringatan)."
                  },
                  "no_match_action": {
                    "type": "string",
                    "enum": [
                      "DECLINE",
                      "NO_ACTION"
                    ],
                    "default": "DECLINE",
                    "description": "Pengaruh `no_match` terhadap `database_validation.status`. Default ke `DECLINE`."
                  },
                  "save_api_request": {
                    "type": "boolean",
                    "default": true,
                    "description": "Simpan validasi sebagai sesi (visibilitas konsol, endpoint keputusan, webhook `status.updated`). Tindakan ini juga mengubah bentuk respons `validations`: objek per layanan saat `true` (default), peta kolom gabungan saat `false`."
                  },
                  "vendor_data": {
                    "type": "string",
                    "description": "Pengenal Anda untuk pengguna yang divalidasi; dikembalikan dan disimpan bersama sesi."
                  },
                  "metadata": {
                    "type": "object",
                    "nullable": true,
                    "description": "JSON bentuk bebas yang disimpan bersama permintaan dan dikembalikan dalam respons."
                  },
                  "selfie": {
                    "type": "string",
                    "format": "binary",
                    "description": "Gambar swafoto (`jpg`, `jpeg`, `png`, `webp`; maks 2 MB — gambar dikompresi menjadi ~1.5 MB sebelum diunggah ke registri) untuk layanan validasi biometrik, mis. RENAPER Argentina (`arg_renaper`) dan SIB Panama (`pan_cedula_sib`, `pan_cedula_sib_plus`). Wajib diisi setiap kali layanan yang dipilih mencantumkannya sebagai kolom yang diperlukan. Hanya tersedia melalui `multipart/form-data`."
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST https://verification.didit.me/v3/database-validation/ \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"issuing_state\": \"BRA\",\n    \"services\": [\"bra_cpf\"],\n    \"identification_number\": \"12345678900\",\n    \"first_name\": \"John\",\n    \"last_name\": \"Doe\",\n    \"date_of_birth\": \"1980-01-01\",\n    \"vendor_data\": \"user-1234\"\n  }'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.database_validation.validate(\n    issuing_state=\"BRA\",\n    services=[\"bra_cpf\"],\n    identification_number=\"12345678900\",\n    first_name=\"John\",\n    last_name=\"Doe\",\n    date_of_birth=\"1980-01-01\",\n    vendor_data=\"user-1234\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.databaseValidation.validate({\n  issuing_state: \"BRA\",\n  services: [\"bra_cpf\"],\n  identification_number: \"12345678900\",\n  first_name: \"John\",\n  last_name: \"Doe\",\n  date_of_birth: \"1980-01-01\",\n  vendor_data: \"user-1234\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.DatabaseValidation.Validate(ctx, didit.DatabaseValidationValidateParams{\n\tIssuingState:         \"BRA\",\n\tServices:             didit.Some([]string{\"bra_cpf\"}),\n\tIdentificationNumber: didit.String(\"12345678900\"),\n\tFirstName:            didit.String(\"John\"),\n\tLastName:             didit.String(\"Doe\"),\n\tDateOfBirth:          didit.String(\"1980-01-01\"),\n\tVendorData:           didit.String(\"user-1234\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.time.LocalDate;\nimport java.util.List;\nimport me.didit.Didit;\nimport me.didit.types.DatabaseValidationValidateParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.databaseValidation().validate(DatabaseValidationValidateParams.builder()\n        .issuingState(\"BRA\")\n        .services(List.of(\"bra_cpf\"))\n        .identificationNumber(\"12345678900\")\n        .firstName(\"John\")\n        .lastName(\"Doe\")\n        .dateOfBirth(LocalDate.parse(\"1980-01-01\"))\n        .vendorData(\"user-1234\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->databaseValidation->validate([\n    'issuing_state' => 'BRA',\n    'services' => ['bra_cpf'],\n    'identification_number' => '12345678900',\n    'first_name' => 'John',\n    'last_name' => 'Doe',\n    'date_of_birth' => '1980-01-01',\n    'vendor_data' => 'user-1234',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.database_validation.validate(\n  issuing_state: \"BRA\",\n  services: [\"bra_cpf\"],\n  identification_number: \"12345678900\",\n  first_name: \"John\",\n  last_name: \"Doe\",\n  date_of_birth: \"1980-01-01\",\n  vendor_data: \"user-1234\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.DatabaseValidation.ValidateAsync(new DatabaseValidationValidateParams\n{\n    IssuingState = \"BRA\",\n    Services = new string[] { \"bra_cpf\" },\n    IdentificationNumber = \"12345678900\",\n    FirstName = \"John\",\n    LastName = \"Doe\",\n    DateOfBirth = \"1980-01-01\",\n    VendorData = \"user-1234\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "Validasi selesai — setidaknya satu layanan yang dipilih mengembalikan hasil yang dapat digunakan. Periksa `database_validation.match_type` untuk hasil agregat, `validations` untuk perbandingan kolom per layanan dan `outcome_code`s, serta `errors` (jika ada) untuk layanan yang gagal.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "request_id": {
                      "type": "string",
                      "format": "uuid",
                      "description": "ID sesi yang disimpan saat `save_api_request=true` (dapat digunakan dengan `GET /v3/session/{sessionId}/decision/`); jika tidak, berupa UUID korelasi sementara."
                    },
                    "database_validation": {
                      "type": "object",
                      "properties": {
                        "status": {
                          "type": "string",
                          "enum": [
                            "Approved",
                            "Declined",
                            "In Review"
                          ],
                          "description": "`Declined` ketika `match_type` keseluruhan memicu tindakan `DECLINE` (`no_match_action` default ke `DECLINE`, `partial_match_action` ke `NO_ACTION`); `In Review` ketika tidak ada layanan yang menghasilkan perbandingan yang dapat digunakan, misalnya ketika satu-satunya layanan yang dipilih menghasilkan `REGISTRY_UNAVAILABLE` atau `INCONCLUSIVE`; `Approved` jika tidak. Permintaan yang memilih beberapa layanan dapat bernilai `Approved` berdasarkan kecocokan satu layanan meskipun layanan lainnya tidak tersedia, jadi periksa juga `errors` dan `outcome_code`s per layanan."
                        },
                        "issuing_state": {
                          "type": "string",
                          "description": "Salinan negara ISO 3166-1 alpha-3 yang digunakan sebagai pembanding untuk validasi.",
                          "example": "BRA"
                        },
                        "validation_type": {
                          "type": "string",
                          "enum": [
                            "one_by_one",
                            "two_by_two"
                          ],
                          "description": "Diturunkan dari hasil: `two_by_two` jika ≥2 layanan berbeda menghasilkan kecocokan penuh (pada nomor identifikasi, pada nama lengkap + tanggal lahir bersamaan, atau pada alamat tanpa kontradiksi); `one_by_one` jika sebaliknya. (Kolom permintaan dengan nama yang sama sudah usang dan diabaikan.)"
                        },
                        "screened_data": {
                          "type": "object",
                          "description": "Menampilkan kembali kolom input yang dikirimkan ke layanan yang dipilih (tanggal dinormalisasi ke `YYYY-MM-DD`; `selfie`, jika dikirimkan, dikembalikan sebagai URL yang telah ditandatangani sebelumnya; `consent_obtained: true` ditambahkan jika persetujuan diberikan)."
                        },
                        "match_type": {
                          "type": "string",
                          "nullable": true,
                          "enum": [
                            "full_match",
                            "partial_match",
                            "no_match"
                          ],
                          "description": "Hasil keseluruhan yang diagregasi di seluruh layanan dengan perbandingan tingkat kolom: apa pun `full_match` → `full_match`; jika tidak, apa pun `partial_match` → `partial_match`; jika tidak, `no_match`. Layanan yang hanya menghasilkan hasil akhir, seperti skrining kriminal biometrik, dapat mengembalikan `null`; periksa setiap item di `validations` untuk melihat `outcome_code`-nya."
                        },
                        "validations": {
                          "description": "Bentuk bergantung pada `save_api_request`. **`true` (default):** array objek per layanan (`service_id`, `service_name`, `validation`, `outcome_code`, `outcome_detail`, `source_data`). **`false`:** satu objek datar yang menggabungkan hasil tingkat kolom dari semua layanan (`{\"full_name\": \"full_match\", ...}`).",
                          "oneOf": [
                            {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "description": "Hasil validasi per layanan (dikembalikan ketika `save_api_request=true`, yaitu nilai bawaan).",
                                "properties": {
                                  "service_id": {
                                    "type": "string",
                                    "description": "ID katalog layanan yang menghasilkan hasil ini (misalnya `bra_cpf`).",
                                    "example": "bra_cpf"
                                  },
                                  "service_name": {
                                    "type": "string",
                                    "description": "Nama katalog layanan yang mudah dibaca manusia.",
                                    "example": "Brazil - CPF status check"
                                  },
                                  "validation": {
                                    "type": "object",
                                    "description": "Perbandingan kolom demi kolom antara input Anda dan catatan registri. Kuncinya adalah nama kolom kanonik (`full_name`, `date_of_birth`, `identification_number`, `address`, …); nilainya adalah `full_match`, `partial_match`, atau `no_match`.",
                                    "additionalProperties": {
                                      "type": "string",
                                      "enum": [
                                        "full_match",
                                        "partial_match",
                                        "no_match"
                                      ]
                                    }
                                  },
                                  "outcome_code": {
                                    "type": "string",
                                    "enum": [
                                      "MATCH",
                                      "PARTIAL_MATCH",
                                      "NO_MATCH",
                                      "DOCUMENT_NOT_FOUND",
                                      "INVALID_DOCUMENT_FORMAT",
                                      "INVALID_INPUT",
                                      "MINOR_BLOCKED",
                                      "DECEASED",
                                      "BIOMETRIC_NO_MATCH",
                                      "BIOMETRIC_IMAGE_UNUSABLE",
                                      "INCONCLUSIVE",
                                      "DOCUMENT_SUPERSEDED",
                                      "REGISTRY_UNAVAILABLE",
                                      "REGISTRY_ERROR"
                                    ],
                                    "description": "Hasil pencarian registri yang netral terhadap vendor. `MATCH`/`PARTIAL_MATCH`/`NO_MATCH` mendeskripsikan perbandingan; `DOCUMENT_NOT_FOUND` berarti pengidentifikasi tidak ada di dalam registri; `INCONCLUSIVE` berarti registri tidak dapat mengonfirmasi salah satunya (diarahkan ke peninjauan — BUKAN no-match); `BIOMETRIC_NO_MATCH` adalah ketidakcocokan wajah yang pasti sedangkan `BIOMETRIC_IMAGE_UNUSABLE` adalah masalah teknis gambar (ambil ulang swafoto); `DECEASED`/`MINOR_BLOCKED` adalah hasil kebijakan registri; `DOCUMENT_SUPERSEDED` berarti identitas cocok tetapi edisi dokumen yang diberikan bukan yang tercatat (edisi yang lebih baru telah diterbitkan); `INVALID_DOCUMENT_FORMAT`/`INVALID_INPUT` berarti registri itu sendiri menolak data yang dikirimkan; `REGISTRY_UNAVAILABLE`/`REGISTRY_ERROR` menunjukkan kegagalan pada sistem hulu."
                                  },
                                  "outcome_detail": {
                                    "type": "string",
                                    "nullable": true,
                                    "description": "Detail status hulu mentah yang mendasari kode hasil (misalnya kode status HTTP atau status registri)."
                                  },
                                  "source_data": {
                                    "type": "object",
                                    "nullable": true,
                                    "description": "Tampilan catatan registri yang telah dibersihkan dan dinormalisasi menggunakan nama kolom kanonikal (`identification_number`, `first_name`, `last_name`, `date_of_birth`, ditambah penanda khusus registri). Kolom gambar, jika ada, dikembalikan sebagai pre-signed URL."
                                  }
                                }
                              }
                            },
                            {
                              "type": "object",
                              "additionalProperties": {
                                "type": "string",
                                "enum": [
                                  "full_match",
                                  "partial_match",
                                  "no_match"
                                ]
                              },
                              "description": "Hasil per kolom yang digabungkan (bentuk tanpa status `save_api_request=false`)."
                            }
                          ]
                        },
                        "warnings": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "feature": {
                                "type": "string",
                                "description": "Fitur yang memunculkan peringatan."
                              },
                              "risk": {
                                "type": "string",
                                "description": "Pengidentifikasi risiko yang dapat dibaca mesin."
                              },
                              "additional_data": {
                                "type": "object",
                                "nullable": true,
                                "description": "Konteks tambahan untuk peringatan, jika tersedia."
                              },
                              "log_type": {
                                "type": "string",
                                "description": "`warning`, `information`, atau `error` — pengaruh risiko terhadap hasilnya."
                              },
                              "short_description": {
                                "type": "string",
                                "description": "Ringkasan satu baris yang dapat dibaca manusia."
                              },
                              "long_description": {
                                "type": "string",
                                "description": "Penjelasan lengkap yang dapat dibaca manusia."
                              }
                            }
                          },
                          "description": "`DATABASE_VALIDATION_NO_MATCH` atau `DATABASE_VALIDATION_PARTIAL_MATCH` jika berlaku; kosong pada kecocokan penuh."
                        },
                        "errors": {
                          "type": "array",
                          "description": "Hadir hanya ketika beberapa (tetapi tidak semua) layanan yang dipilih gagal. Setiap entri memuat `service_id`, `code`, `message`, dan `retryable`. Layanan yang dilaporkan di sini tidak ada di `validations` dan `services_used`, serta tidak ditagih. Array ini adalah satu-satunya tempat kemunculannya, jadi periksa array ini bahkan ketika `status` bernilai `Approved`.",
                          "items": {
                            "type": "object",
                            "properties": {
                              "service_id": {
                                "type": "string"
                              },
                              "code": {
                                "type": "string",
                                "example": "empty_provider_response"
                              },
                              "message": {
                                "type": "string"
                              },
                              "retryable": {
                                "type": "boolean",
                                "description": "`true` saat layanan tidak menghasilkan jawaban dan mencobanya lagi nanti dapat berhasil; `false` saat sumber menolak data yang dikirim dan input harus diperbaiki terlebih dahulu.",
                                "example": true
                              }
                            }
                          }
                        },
                        "services_used": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          },
                          "description": "ID katalog dari layanan yang mengembalikan hasil yang dapat ditagihkan. **Hanya ada jika permintaan secara eksplisit mengirimkan `services`.**"
                        },
                        "match_score": {
                          "type": "number",
                          "description": "Fraksi (0.0–1.0) dari layanan yang dicoba yang menghasilkan kecocokan penuh (pada nomor identifikasi, pada nama lengkap + tanggal lahir bersama-sama, atau pada alamat tanpa kontradiksi). **Hanya ada jika permintaan secara eksplisit mengirimkan `services`.**"
                        }
                      }
                    },
                    "vendor_data": {
                      "type": "string",
                      "nullable": true,
                      "description": "Menampilkan kembali `vendor_data` yang Anda kirimkan."
                    },
                    "metadata": {
                      "type": "object",
                      "nullable": true,
                      "description": "Salinan `metadata` yang Anda kirimkan."
                    },
                    "created_at": {
                      "type": "string",
                      "format": "date-time"
                    }
                  }
                },
                "examples": {
                  "Full match (Approved)": {
                    "summary": "Default save_api_request=true — objek `validations` per layanan",
                    "value": {
                      "request_id": "7f9a1c0e-1f2b-4f6e-9d3a-2b1c0e7f9a1c",
                      "database_validation": {
                        "status": "Approved",
                        "issuing_state": "BRA",
                        "validation_type": "one_by_one",
                        "screened_data": {
                          "tax_number": "12345678900",
                          "first_name": "John",
                          "last_name": "Doe",
                          "date_of_birth": "1980-01-01"
                        },
                        "match_type": "full_match",
                        "validations": [
                          {
                            "validation": {
                              "full_name": "full_match",
                              "date_of_birth": "full_match",
                              "identification_number": "full_match"
                            },
                            "outcome_code": "MATCH",
                            "outcome_detail": "200",
                            "service_id": "bra_cpf",
                            "service_name": "Brazil - CPF status check",
                            "source_data": {
                              "identification_number": "12345678900",
                              "first_name": "JOHN",
                              "last_name": "DOE",
                              "date_of_birth": "1980-01-01",
                              "lgpd_minor": false,
                              "minor_under_16": false,
                              "minor_under_18": false
                            }
                          }
                        ],
                        "warnings": []
                      },
                      "vendor_data": "user-1234",
                      "metadata": null,
                      "created_at": "2026-06-11T10:30:00.000000+00:00"
                    }
                  },
                  "Explicit services (extended shape)": {
                    "summary": "Permintaan dengan `services` dikirim — respons menambahkan `services_used` dan `match_score`",
                    "value": {
                      "request_id": "b3e7c1a2-9d4f-4f0b-8a6c-5e2d1f0a9b3e",
                      "database_validation": {
                        "status": "Approved",
                        "issuing_state": "BRA",
                        "validation_type": "one_by_one",
                        "screened_data": {
                          "tax_number": "12345678900",
                          "first_name": "John",
                          "last_name": "Doe",
                          "date_of_birth": "1980-01-01"
                        },
                        "match_type": "full_match",
                        "validations": [
                          {
                            "validation": {
                              "full_name": "full_match",
                              "date_of_birth": "full_match",
                              "identification_number": "full_match"
                            },
                            "outcome_code": "MATCH",
                            "outcome_detail": "200",
                            "service_id": "bra_cpf",
                            "service_name": "Brazil - CPF status check",
                            "source_data": {
                              "identification_number": "12345678900",
                              "first_name": "JOHN",
                              "last_name": "DOE",
                              "date_of_birth": "1980-01-01",
                              "lgpd_minor": false,
                              "minor_under_16": false,
                              "minor_under_18": false
                            }
                          }
                        ],
                        "warnings": [],
                        "services_used": [
                          "bra_cpf"
                        ],
                        "match_score": 1.0
                      },
                      "vendor_data": "user-1234",
                      "metadata": null,
                      "created_at": "2026-06-11T10:30:00.000000+00:00"
                    }
                  },
                  "No match (Declined)": {
                    "summary": "Catatan registri tidak cocok — default `no_match_action=DECLINE`",
                    "value": {
                      "request_id": "0a1b2c3d-4e5f-6789-abcd-ef0123456789",
                      "database_validation": {
                        "status": "Declined",
                        "issuing_state": "BRA",
                        "validation_type": "one_by_one",
                        "screened_data": {
                          "tax_number": "12345678900",
                          "first_name": "John",
                          "last_name": "Doe",
                          "date_of_birth": "1980-01-01"
                        },
                        "match_type": "no_match",
                        "validations": [
                          {
                            "validation": {
                              "full_name": "no_match",
                              "date_of_birth": "no_match",
                              "identification_number": "no_match"
                            },
                            "outcome_code": "NO_MATCH",
                            "outcome_detail": "200",
                            "service_id": "bra_cpf",
                            "service_name": "Brazil - CPF status check",
                            "source_data": {
                              "identification_number": "00987654321",
                              "first_name": "TOTALLY",
                              "last_name": "DIFFERENT NAME",
                              "date_of_birth": "1999-01-01",
                              "lgpd_minor": false,
                              "minor_under_16": false,
                              "minor_under_18": false
                            }
                          }
                        ],
                        "warnings": [
                          {
                            "feature": "DATABASE_VALIDATION",
                            "risk": "DATABASE_VALIDATION_NO_MATCH",
                            "additional_data": null,
                            "log_type": "error",
                            "short_description": "Database validation no match",
                            "long_description": "The system identified a no match in the database validation, requiring further investigation."
                          }
                        ]
                      },
                      "vendor_data": null,
                      "metadata": null,
                      "created_at": "2026-06-11T10:31:00.000000+00:00"
                    }
                  },
                  "Stateless (save_api_request=false)": {
                    "summary": "`validations` diciutkan menjadi pemetaan kolom gabungan; tidak ada yang disimpan",
                    "value": {
                      "request_id": "c4d5e6f7-8901-2345-6789-abcdef012345",
                      "database_validation": {
                        "status": "Approved",
                        "issuing_state": "BRA",
                        "validation_type": "one_by_one",
                        "screened_data": {
                          "tax_number": "12345678900",
                          "first_name": "John",
                          "last_name": "Doe",
                          "date_of_birth": "1980-01-01"
                        },
                        "match_type": "full_match",
                        "validations": {
                          "full_name": "full_match",
                          "date_of_birth": "full_match",
                          "identification_number": "full_match"
                        },
                        "warnings": []
                      },
                      "vendor_data": null,
                      "metadata": null,
                      "created_at": "2026-06-11T10:32:00.000000+00:00"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Kesalahan validasi - tidak ada yang ditagih. Kesalahan kolom preflight terjadi sebelum panggilan eksternal apa pun. Jika setiap percobaan yang belum terjawab secara eksplisit menolak input, respons akan menyertakan `validation_errors` dengan `code: provider_rejected_input` dan `retryable: false`; perbaiki input sebelum mencoba lagi. Masalah tingkat kolom menggunakan envelope standar DRF; masalah katalog mengembalikan array `services` (ditambah `requires_onboarding` atau `services_requiring_consent` jika relevan); kesalahan kolom yang hilang menyertakan `fields_required_by` yang memetakan setiap kolom yang hilang ke layanan yang membutuhkannya; layanan yang memerlukan setidaknya satu pengidentifikasi tambahan (misalnya `usa_states_credit_bureau`, yang tidak dapat memverifikasi nama saja) mengembalikan `any_field_required_by` yang memetakan setiap layanan ke kolom yang setidaknya salah satunya harus ada; masalah format yang diperiksa per layanan mengembalikan `invalid_fields_by_service`.",
            "content": {
              "application/json": {
                "examples": {
                  "Invalid issuing_state": {
                    "summary": "Negara tidak didukung — pesan mencantumkan setiap kode alpha-3 yang valid",
                    "value": {
                      "error": [
                        "Invalid issuing state. Valid options are: ARE, ARG, AUS, AUT, BEL, BGD, BOL, BRA, CAN, CHE, CHL, CHN, CIV, COL, CRI, CZE, DEU, DNK, DOM, ECU, ESP, FIN, FRA, GBR, GHA, GLB, GRC, GTM, HKG, HND, IDN, IND, IRL, ITA, KEN, KHM, MAR, MEX, MYS, NGA, NLD, NOR, NZL, OMN, PAN, PER, PHL, POL, PRT, PRY, QAT, SGP, SLV, SVK, SWE, THA, UGA, URY, USA, VEN, ZAF, ZMB, ZWE"
                      ]
                    }
                  },
                  "Missing required fields": {
                    "summary": "Gabungan kolom yang wajib diisi di seluruh layanan yang dipilih, dengan petunjuk kolom universal",
                    "value": {
                      "error": [
                        "Missing required fields: tax_number (or use 'identification_number' which maps to 'tax_number' for BRA)"
                      ],
                      "fields_required_by": {
                        "tax_number": [
                          "bra_cpf"
                        ]
                      }
                    }
                  },
                  "Unknown service id": {
                    "summary": "`services` memuat id yang tidak ada di dalam katalog",
                    "value": {
                      "services": [
                        "Unknown service_id(s): ['bogus_service']"
                      ]
                    }
                  },
                  "Service not live for country": {
                    "summary": "`services` menyebutkan layanan dari negara lain (atau entri sementara)",
                    "value": {
                      "services": [
                        "Services not currently live for PER: ['bra_cpf']. Available services: ['per_dni', 'per_residential', 'per_tax_registration']"
                      ]
                    }
                  },
                  "Service requires onboarding": {
                    "summary": "Layanan ada tetapi belum diaktifkan untuk organisasi Anda",
                    "value": {
                      "services": [
                        "Services require onboarding before they can be enabled for AUS: ['aus_australia_driver_licence']. Contact Didit support to activate them."
                      ],
                      "requires_onboarding": [
                        "aus_australia_driver_licence"
                      ]
                    }
                  },
                  "Consent missing": {
                    "summary": "Layanan yang dipilih ditandai requires_consent=true dan `consent` tidak bernilai `true`",
                    "value": {
                      "consent": [
                        "Explicit end-user consent is required for these database validation services: ['chn_national_id']. Send `consent=true`."
                      ],
                      "services_requiring_consent": [
                        "chn_national_id"
                      ]
                    }
                  },
                  "Country format rule violation": {
                    "summary": "Pengenal tidak memenuhi aturan format negara (panjang/digit/regex)",
                    "value": {
                      "tax_number": [
                        "Invalid tax number for BRA: Brazilian CPF (exactly 11 digits). Must be exactly 11 characters long (got 10)."
                      ]
                    }
                  },
                  "Service-specific format violation": {
                    "summary": "Kolom tidak memenuhi persyaratan format dari layanan yang dipilih",
                    "value": {
                      "error": [
                        "One or more fields do not match the format required by the selected service."
                      ],
                      "invalid_fields_by_service": {
                        "chn_national_id": [
                          "national_id_format"
                        ]
                      }
                    }
                  },
                  "Input refused by every attempt": {
                    "summary": "Koreksi input sebelum mencoba lagi",
                    "value": {
                      "error": "The source refused to run this query with the supplied input.",
                      "validation_errors": [
                        {
                          "service_id": "bra_cpf",
                          "code": "provider_rejected_input",
                          "message": "The source refused to run this query with the supplied input.",
                          "retryable": false
                        }
                      ]
                    }
                  }
                },
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "properties": {
                    "error": {
                      "description": "Penjelasan pada tingkat permintaan atau kesalahan kolom pra-pemeriksaan.",
                      "oneOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        }
                      ]
                    },
                    "validation_errors": {
                      "type": "array",
                      "description": "Hadir ketika setiap upaya yang tidak terjawab menolak input setelah preflight.",
                      "items": {
                        "type": "object",
                        "properties": {
                          "service_id": {
                            "type": "string"
                          },
                          "code": {
                            "type": "string"
                          },
                          "message": {
                            "type": "string"
                          },
                          "retryable": {
                            "type": "boolean",
                            "description": "Menentukan apakah mencoba lagi nanti dapat menyelesaikan kegagalan layanan ini. False berarti perbaiki input yang diberikan terlebih dahulu."
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Izin ditolak. Dikembalikan ketika header `x-api-key` tidak ada, dan juga ketika saldo organisasi pemanggil tidak dapat mencukupi biaya panggilan tersebut; kunci yang salah, dicabut, atau kedaluwarsa mengembalikan `401`. Kunci yang tidak ada mengembalikan `403` dengan `{\"detail\": ...}`; kunci yang salah, dicabut, atau kedaluwarsa mengembalikan `401`. Kekurangan kredit mengembalikan `403` dengan `{\"error\": ...}` sebelum skrining atau panggilan penyedia apa pun terjadi.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing or invalid API key": {
                    "summary": "Tidak ada header `x-api-key`, atau kuncinya tidak valid/dicabut",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Not enough credits": {
                    "summary": "Saldo organisasi tidak mencukupi untuk panggilan ini",
                    "value": {
                      "error": "You don't have enough credits to perform this request. Please top up at https://business.didit.me"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Batas laju terlampaui. Endpoint POST/PATCH/DELETE berbagi anggaran 300 permintaan penulisan per menit per kunci API (pembuatan transaksi dan ingesti event memiliki anggaran terpisah sebesar 600). Respons menyertakan header `X-RateLimit-Limit`, `X-RateLimit-Remaining`, `X-RateLimit-Reset`, dan `Retry-After`.",
            "content": {
              "application/json": {
                "examples": {
                  "Write rate limit exceeded": {
                    "summary": "Lebih dari 300 permintaan tulis pada menit ini",
                    "value": {
                      "detail": "Write request rate limit exceeded. You can make up to 300 requests per minute."
                    }
                  }
                },
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "502": {
            "description": "Tidak ada layanan yang dipilih mengembalikan hasil yang dapat digunakan. Periksa setiap entri validation_errors sebelum mencoba lagi; HTTP 502 saja tidak menunjukkan kegagalan sementara. empty_provider_response dengan retryable: true menunjukkan hasil yang tidak tersedia atau tidak dapat dijelaskan, termasuk layanan utama yang ditolak diikuti oleh fallback yang tidak tersedia. Entri lama provider_invalid_input dan provider_validation_error justru memerlukan input yang dikoreksi dan mungkin tidak menyertakan retryable. Tidak ada yang ditagihkan. Jika save_api_request=true, upaya yang gagal dicatat sebagai sesi dengan status Not Finished. Kegagalan parsial mengembalikan 200 dengan database_validation.errors.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "validation_errors": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "service_id": {
                            "type": "string"
                          },
                          "code": {
                            "type": "string"
                          },
                          "message": {
                            "type": "string"
                          },
                          "retryable": {
                            "type": "boolean",
                            "description": "Menentukan apakah mencoba lagi nanti dapat menyelesaikan kegagalan layanan ini. False berarti perbaiki input yang diberikan terlebih dahulu."
                          }
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "Provider returned no result": {
                    "summary": "Setiap layanan yang dipilih gagal",
                    "value": {
                      "error": "Database validation could not be performed. The external validation service did not return a result. Please try again later.",
                      "validation_errors": [
                        {
                          "service_id": "bra_cpf",
                          "code": "empty_provider_response",
                          "message": "The provider did not return a database validation result.",
                          "retryable": true
                        }
                      ]
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v3/phone/send/": {
      "post": {
        "summary": "Kirim Kode Telepon",
        "description": "Kirim kode sekali pakai (OTP) ke nomor telepon melalui WhatsApp, SMS, atau saluran lain yang didukung, lalu verifikasi dengan [`POST /v3/phone/check/`](/id/standalone-apis/phone-check).\n\n**Cara pengiriman dan pemeriksaan berpasangan.** Status verifikasi diidentifikasi berdasarkan aplikasi Anda ditambah `phone_number` E.164 — panggilan pemeriksaan tidak memerlukan `request_id`. Setiap pengiriman baru membuat verifikasi tertunda yang aktif selama **5 menit**: panggil pemeriksaan dengan nomor yang sama dan kode yang diterima pengguna sebelum batas waktu berakhir. Memanggil pengiriman lagi untuk nomor yang sama saat verifikasi masih tertunda akan mengirim ulang kode untuk verifikasi yang sama (`status: \"Retry\"`, `request_id` yang sama). Paling banyak satu percobaan ulang dilampirkan dengan cara ini (total dua kali pengiriman); pengiriman berikutnya akan memulai verifikasi baru dengan `request_id` baru. Batas waktu 5 menit dihitung dari pengiriman pertama dan tidak diperpanjang oleh percobaan ulang.\n\n**Saluran pengiriman.** `options.preferred_channel` memilih saluran (secara default `whatsapp`; `sms`, `telegram`, `voice`, `rcs`, `viber`, dan `zalo` juga didukung). Jika saluran pilihan tidak tersedia untuk negara atau nomor tujuan, pengiriman secara otomatis dialihkan ke SMS — pengiriman tetap melaporkan `Success`, dan saluran yang sebenarnya digunakan dilaporkan oleh respons pemeriksaan (`phone.verification_method` dan event `lifecycle`).\n\n**Branding.** Kode SMS menyertakan nama pengirim SMS aplikasi Anda, yang diatur di Business Console, tanpa biaya tambahan. Teruskan `options.sms_sender_name` untuk mengirim satu kode dengan nama lain, atau `options.use_white_label_customization: true` untuk beralih ke nama publik White Label Anda jika tidak ada nama pengirim yang diatur. Kode WhatsApp menggunakan pesan tetap; hubungkan nomor WhatsApp Business Anda sendiri di Business Console untuk mengirimkannya dari nama dan nomor bisnis Anda, ditagihkan hanya dengan biaya Didit.\n\n**Status pengiriman.** `Success` — OTP dikirim untuk verifikasi baru; `Retry` — OTP dikirim ulang untuk verifikasi tertunda; `Blocked` — lapisan antipenipuan menolak untuk mengirim (lihat `reason`, mis. `repeated_attempts`, `suspicious`, `spam`). Pengiriman `Blocked` segera menyelesaikan verifikasi sebagai `Declined` dengan peringatan risiko tinggi, sehingga pemeriksaan lanjutan mengembalikan `Expired or Not Found`.\n\n**Penagihan.** Harga bergantung pada negara tujuan dan saluran yang benar-benar mengirimkan pesan — lihat [Harga Verifikasi Telepon](/id/getting-started/phone-verification-pricing). Hanya pengiriman `Blocked` yang dijamin gratis: setiap upaya pengiriman lain yang belum ditagih akan dikenakan biaya saat finalisasi atau kedaluwarsa verifikasi, bahkan jika pengiriman tidak pernah dikonfirmasi atau penyedia pengiriman melaporkan pesan tidak dapat terkirim. Pemeriksaan selalu gratis. Sebagai langkah antipenyalahgunaan, verifikasi telepon dinonaktifkan hingga isi saldo pertama organisasi Anda (`403`).\n\n**Persistensi sesi.** Setiap verifikasi baru disimpan secara persisten sebagai sesi bertipe API: `request_id` adalah id sesi sebenarnya yang dapat Anda teruskan ke `GET /v3/session/{sessionId}/decision/`, verifikasi muncul di Business Console, dan webhook `status.updated` dipicu seiring perkembangannya.\n\n**Sandbox.** Kunci API sandbox melewati pengiriman dan penagihan: setelah validasi permintaan (input yang tidak sesuai tetap mengembalikan `400`), endpoint mengembalikan payload `Success` statis dengan `request_id` acak; tidak ada pesan yang dikirim dan tidak ada yang disimpan. Gunakan kode `123456` pada pemeriksaan sandbox.\n\n**Autentikasi.** Kirim kunci API aplikasi Anda di header `x-api-key`. Kredensial yang hilang atau tidak valid mengembalikan `403` (`{\"detail\": \"You do not have permission to perform this action.\"}`) — API ini tidak pernah mengembalikan `401`.\n\n**Batas laju.** Kuota penulisan bersama sebesar 300 permintaan/menit per kunci API di semua endpoint POST/PATCH/DELETE, ditambah batas antipenyalahgunaan sebanyak 4 upaya pengiriman per nomor telepon per jam; melebihi salah satunya akan mengembalikan `429`.",
        "operationId": "post_v3phone_send",
        "x-didit-sdk": {
          "resource": "phone",
          "method": "send_code",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Standalone APIs"
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST https://verification.didit.me/v3/phone/send/ \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"phone_number\": \"+14155552671\",\n    \"options\": {\n      \"code_size\": 6,\n      \"preferred_channel\": \"whatsapp\",\n      \"locale\": \"en-US\"\n    },\n    \"vendor_data\": \"user-1234\"\n  }'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.phone.send_code(\n    phone_number=\"+14155552671\",\n    options={\n        \"locale\": \"en-US\",\n        \"preferred_channel\": \"whatsapp\",\n    },\n    vendor_data=\"user-1234\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.phone.sendCode({\n  phone_number: \"+14155552671\",\n  options: {\n    locale: \"en-US\",\n    preferred_channel: \"whatsapp\",\n  },\n  vendor_data: \"user-1234\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Phone.SendCode(ctx, didit.PhoneSendCodeParams{\n\tPhoneNumber: \"+14155552671\",\n\tOptions: didit.Some(didit.PhoneSendCodeParamsOptions{\n\t\tLocale:           didit.String(\"en-US\"),\n\t\tPreferredChannel: didit.Some(didit.PhoneSendCodeParamsOptionsPreferredChannel(\"whatsapp\")),\n\t}),\n\tVendorData: didit.String(\"user-1234\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.PhoneSendCodeParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.phone().sendCode(PhoneSendCodeParams.builder()\n        .phoneNumber(\"+14155552671\")\n        .options(PhoneSendCodeParams.Options.builder()\n                .locale(\"en-US\")\n                .preferredChannel(PhoneSendCodeParams.Options.PreferredChannel.of(\"whatsapp\"))\n                .build())\n        .vendorData(\"user-1234\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->phone->sendCode([\n    'phone_number' => '+14155552671',\n    'options' => [\n        'locale' => 'en-US',\n        'preferred_channel' => 'whatsapp',\n    ],\n    'vendor_data' => 'user-1234',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.phone.send_code(\n  phone_number: \"+14155552671\",\n  options: {\n    locale: \"en-US\",\n    preferred_channel: \"whatsapp\",\n  },\n  vendor_data: \"user-1234\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Phone.SendCodeAsync(new PhoneSendCodeParams\n{\n    PhoneNumber = \"+14155552671\",\n    Options = new PhoneSendCodeParamsOptions\n    {\n        Locale = \"en-US\",\n        PreferredChannel = new PhoneSendCodeParamsOptionsPreferredChannel(\"whatsapp\"),\n    },\n    VendorData = \"user-1234\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "phone_number": {
                    "type": "string",
                    "maxLength": 20,
                    "description": "Nomor telepon penerima dalam format E.164 — diawali tanda `+` dan kode negara (misalnya, `+14155552671`). Nomor divalidasi dan dinormalisasi ke E.164; nomor yang tidak dapat diuraikan atau tidak valid mengembalikan `400` dengan kesalahan kolom `phone_number`.",
                    "example": "+14155552671"
                  },
                  "options": {
                    "type": "object",
                    "description": "Opsi pengiriman OTP. Semua kolom bersifat opsional.",
                    "properties": {
                      "code_size": {
                        "type": "integer",
                        "minimum": 4,
                        "maximum": 8,
                        "default": 6,
                        "description": "Jumlah digit dalam OTP."
                      },
                      "locale": {
                        "type": "string",
                        "maxLength": 5,
                        "pattern": "^[a-z]{2,3}(-[A-Z]{2,3})?$",
                        "description": "Lokal BCP-47 yang digunakan untuk melokalisasi pesan verifikasi (misalnya, `en-US`, `fr`, `es`). Format yang tidak valid mengembalikan `400`.",
                        "example": "en-US"
                      },
                      "preferred_channel": {
                        "type": "string",
                        "enum": [
                          "whatsapp",
                          "sms",
                          "telegram",
                          "voice",
                          "rcs",
                          "viber",
                          "zalo"
                        ],
                        "default": "whatsapp",
                        "description": "Saluran pengiriman pilihan. Jika saluran tidak tersedia untuk negara atau nomor tujuan, pesan secara otomatis beralih ke SMS — pengiriman tetap melaporkan `Success`."
                      },
                      "use_white_label_customization": {
                        "type": "boolean",
                        "default": false,
                        "description": "Jika `true`, pengiriman berlabel White Label: jika aplikasi Anda tidak memiliki nama pengirim SMS, SMS akan menyebutkan nama publik White Label Anda (\"123456 adalah kode verifikasi Anda untuk Acme Bank\"). Nama pengirim SMS Anda, jika diatur, akan digunakan dengan atau tanpa tanda ini. Berlaku untuk pesan SMS, termasuk fallback SMS dari saluran lain; kode WhatsApp dikirim dengan pesan tetap dan tidak menggunakan branding. Default ke `false`."
                      },
                      "sms_sender_name": {
                        "type": "string",
                        "nullable": true,
                        "maxLength": 30,
                        "example": "Acme Bank",
                        "description": "Nama yang dicantumkan pada SMS kode ini (\"123456 adalah kode verifikasi Anda untuk Acme Bank\"), alih-alih nama pengirim SMS aplikasi Anda. Gratis. 1 hingga 30 karakter: hanya huruf, angka, spasi, dan ' & - !, bukan hanya angka, dengan spasi tunggal antarkata; nilai lain apa pun akan mengembalikan `400` dan tidak ada kode yang dikirim. Jika tidak dicantumkan, bernilai `null`, atau kosong, nama pengirim SMS aplikasi Anda yang akan digunakan. Setiap aplikasi dapat mulai menggunakan hingga dua nama baru per hari (UTC); lebih dari itu, kode dikirim dengan nama aplikasi Anda. Berlaku untuk pesan SMS, termasuk SMS cadangan dari saluran lain; kode WhatsApp tidak diberi merek.",
                        "pattern": "^$|^(?![\\d ]+$)[\\p{L}\\p{N}'&!-]+( [\\p{L}\\p{N}'&!-]+)*$"
                      }
                    }
                  },
                  "signals": {
                    "type": "object",
                    "description": "Sinyal perangkat dan jaringan opsional mengenai pengguna akhir, yang diteruskan ke lapisan anti-fraud untuk meningkatkan deteksi lalu lintas yang menyalahgunakan sistem atau dihasilkan secara otomatis. Semua kolom bersifat opsional.",
                    "properties": {
                      "ip": {
                        "type": "string",
                        "description": "Alamat IP perangkat pengguna akhir. IPv4 atau IPv6.",
                        "example": "192.0.2.1"
                      },
                      "device_id": {
                        "type": "string",
                        "maxLength": 255,
                        "description": "Pengenal unik perangkat pengguna akhir. Android: `ANDROID_ID`; iOS: `identifierForVendor`.",
                        "example": "8F0B8FDD-C2CB-4387-B20A-56E9B2E5A0D2"
                      },
                      "device_platform": {
                        "type": "string",
                        "enum": [
                          "android",
                          "ios",
                          "ipados",
                          "tvos",
                          "web"
                        ],
                        "description": "Platform perangkat pengguna akhir."
                      },
                      "device_model": {
                        "type": "string",
                        "maxLength": 255,
                        "description": "Model perangkat pengguna akhir.",
                        "example": "iPhone17,2"
                      },
                      "os_version": {
                        "type": "string",
                        "maxLength": 64,
                        "description": "Versi sistem operasi dari perangkat pengguna akhir.",
                        "example": "18.0.1"
                      },
                      "app_version": {
                        "type": "string",
                        "maxLength": 64,
                        "description": "Versi aplikasi Anda.",
                        "example": "1.2.34"
                      },
                      "user_agent": {
                        "type": "string",
                        "maxLength": 512,
                        "description": "User agent dari browser atau aplikasi pengguna akhir.",
                        "example": "Mozilla/5.0 (iPhone; CPU iPhone OS 14_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0.3 Mobile/15E148 Safari/604.1"
                      }
                    }
                  },
                  "vendor_data": {
                    "type": "string",
                    "description": "Pengidentifikasi opsional yang dikontrol pemanggil (id pengguna internal Anda, email, UUID, dll.) yang disimpan pada sesi dan dikembalikan dalam respons pengiriman, respons pemeriksaan kecocokan, webhook, dan Business Console. Gunakan ini untuk menghubungkan `request_id` Didit dengan data pengguna Anda."
                  },
                  "metadata": {
                    "type": "object",
                    "nullable": true,
                    "description": "Objek JSON bentuk bebas opsional yang disimpan pada sesi dan dikembalikan dalam respons pengiriman, respons pemeriksaan pencocokan, webhook, dan Business Console."
                  }
                },
                "required": [
                  "phone_number"
                ]
              },
              "examples": {
                "WhatsApp (default)": {
                  "summary": "OTP 6 digit via WhatsApp, beralih ke SMS secara otomatis jika gagal",
                  "value": {
                    "phone_number": "+14155552671",
                    "options": {
                      "preferred_channel": "whatsapp",
                      "locale": "en-US"
                    },
                    "vendor_data": "user-1234"
                  }
                },
                "SMS with custom code length": {
                  "summary": "Paksa pengiriman SMS dengan kode 4 digit",
                  "value": {
                    "phone_number": "+34699999999",
                    "options": {
                      "preferred_channel": "sms",
                      "code_size": 4,
                      "locale": "es"
                    }
                  }
                },
                "With fraud signals": {
                  "summary": "Teruskan sinyal perangkat untuk memperkuat skrining antifraud",
                  "value": {
                    "phone_number": "+14155552671",
                    "signals": {
                      "ip": "192.0.2.1",
                      "device_id": "8F0B8FDD-C2CB-4387-B20A-56E9B2E5A0D2",
                      "device_platform": "ios",
                      "device_model": "iPhone17,2",
                      "os_version": "18.0.1",
                      "app_version": "1.2.34"
                    },
                    "vendor_data": "user-1234"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Pengiriman dikonfirmasi. Periksa `status`: `Success` dan `Retry` berarti kode sedang dikirim; `Blocked` berarti lapisan antipenipuan menolak dan verifikasi telah difinalisasi sebagai `Declined`. `request_id` adalah id sesi yang disimpan (id yang sama pada `Retry`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PhoneVerificationSendResponse"
                },
                "examples": {
                  "Success": {
                    "summary": "OTP terkirim untuk verifikasi baru",
                    "value": {
                      "request_id": "e39cb057-92fc-4b59-b84e-02fec29a0f24",
                      "status": "Success",
                      "reason": null,
                      "vendor_data": "user-1234",
                      "metadata": null
                    }
                  },
                  "Retry": {
                    "summary": "Pengiriman kedua untuk nomor yang sama dalam jendela 5 menit — request_id yang sama",
                    "value": {
                      "request_id": "e39cb057-92fc-4b59-b84e-02fec29a0f24",
                      "status": "Retry",
                      "reason": null,
                      "vendor_data": "user-1234",
                      "metadata": null
                    }
                  },
                  "Blocked": {
                    "summary": "Penolakan antipenipuan — verifikasi difinalisasi sebagai Ditolak, tidak ada yang ditagih",
                    "value": {
                      "request_id": "0d8af1f4-0c43-46d7-b75c-6e4e22c0a7b3",
                      "status": "Blocked",
                      "reason": "repeated_attempts",
                      "vendor_data": "user-1234",
                      "metadata": null
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Kesalahan validasi. Input yang salah format mengembalikan envelope kesalahan kolom DRF (satu array pesan per kolom yang bermasalah, bersarang di bawah `options` untuk kesalahan opsi). Nomor yang berhasil di-parse tetapi ditolak pada saat pengiriman (tidak dapat dihubungi, atau jenis saluran yang tidak memenuhi syarat seperti kode pendek) mengembalikan envelope `{\"detail\": ...}` sebagai gantinya.",
            "content": {
              "application/json": {
                "examples": {
                  "Invalid phone number (field error)": {
                    "summary": "Nomor bukan format E.164 yang valid",
                    "value": {
                      "phone_number": [
                        "Invalid phone number provided."
                      ]
                    }
                  },
                  "Missing phone number": {
                    "summary": "`phone_number` tidak disertakan di dalam body",
                    "value": {
                      "phone_number": [
                        "This field is required."
                      ]
                    }
                  },
                  "Invalid options": {
                    "summary": "`code_size` di luar rentang, `locale` salah format, `preferred_channel` tidak dikenal",
                    "value": {
                      "options": {
                        "code_size": [
                          "Ensure this value is less than or equal to 8."
                        ],
                        "locale": [
                          "Ensure this field has no more than 5 characters."
                        ],
                        "preferred_channel": [
                          "\"carrier_pigeon\" is not a valid choice."
                        ]
                      }
                    }
                  },
                  "Number rejected at send time": {
                    "summary": "Format E.164 valid tetapi nomor tidak dapat menerima OTP",
                    "value": {
                      "detail": "Invalid phone number provided."
                    }
                  },
                  "Ineligible line type": {
                    "summary": "Jenis saluran tidak dapat menerima OTP (misalnya, short code)",
                    "value": {
                      "detail": "Invalid phone line type provided."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Izin ditolak. Dikembalikan ketika header `x-api-key` tidak ada (`{\"detail\": ...}`); kunci yang salah, dicabut, atau kedaluwarsa mengembalikan `401`. Juga dikembalikan sebelum pengiriman apa pun ketika organisasi belum pernah mengisi saldo (pencegahan penyalahgunaan) atau ketika saldonya tidak dapat mencakup harga pengiriman tujuan (`{\"error\": ...}`).",
            "content": {
              "application/json": {
                "examples": {
                  "Missing or invalid API key": {
                    "summary": "Tidak ada header `x-api-key`, atau kuncinya tidak valid/dicabut",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Top-up required": {
                    "summary": "Verifikasi telepon tetap dinonaktifkan hingga organisasi melakukan pengisian saldo pertama",
                    "value": {
                      "detail": "To protect against abuse, phone verification is disabled until your first top-up."
                    }
                  },
                  "Not enough credits": {
                    "summary": "Saldo organisasi tidak mencukupi untuk harga pengiriman",
                    "value": {
                      "error": "You don't have enough credits to perform this request."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Batas laju terlampaui. Endpoint POST/PATCH/DELETE berbagi anggaran 300 permintaan penulisan per menit per kunci API (pembuatan transaksi dan ingesti event memiliki anggaran terpisah sebesar 600). Selain itu, batas atas anti-penyalahgunaan sebanyak 4 upaya verifikasi per nomor telepon per jam berlaku di sisi hulu. Respons menyertakan header `X-RateLimit-Limit`, `X-RateLimit-Remaining`, `X-RateLimit-Reset`, dan `Retry-After`. Catatan: header `X-RateLimit-*`/`Retry-After` hanya menyertai 429 batas penulisan 300/menit; 429 batas per nomor tidak menyertakan header batas laju.",
            "content": {
              "application/json": {
                "examples": {
                  "Per-number cap": {
                    "summary": "Lebih dari 4 upaya verifikasi untuk nomor yang sama dalam satu jam terakhir",
                    "value": {
                      "detail": "Maximum verification attempts reached for this phone number. Only 4 authentication attempts are allowed per hour. Try again later or use a different number."
                    }
                  },
                  "Write rate limit exceeded": {
                    "summary": "Lebih dari 300 permintaan tulis pada menit ini",
                    "value": {
                      "detail": "Write request rate limit exceeded. You can make up to 300 requests per minute."
                    }
                  }
                },
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "502": {
            "description": "Penyedia verifikasi telepon sementara tidak tersedia - respons 5xx, batas waktu habis (timeout), atau kegagalan koneksi yang tetap terjadi setelah coba lagi bawaan. Aman untuk dicoba lagi; tidak ada biaya yang ditagihkan dan tidak ada upaya yang terpakai.",
            "content": {
              "application/json": {
                "examples": {
                  "Provider outage": {
                    "summary": "Penyedia tidak menjawab permintaan pengiriman",
                    "value": {
                      "detail": "Phone verification is temporarily unavailable. Please try again shortly.",
                      "code": "phone_provider_unavailable"
                    }
                  }
                },
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Kegagalan tak terduga saat membuat verifikasi yang bukan disebabkan oleh gangguan penyedia yang sudah diketahui. Aman untuk dicoba lagi.",
            "content": {
              "application/json": {
                "examples": {
                  "Provider error": {
                    "summary": "Pengiriman OTP tidak dapat diinisiasi",
                    "value": {
                      "detail": "Error creating phone verification"
                    }
                  }
                },
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/phone/check/": {
      "post": {
        "summary": "Periksa Kode Telepon",
        "description": "Verifikasi OTP yang dikirimkan oleh [`POST /v3/phone/send/`](/id/standalone-apis/phone-send) dan dapatkan hasil verifikasi akhir beserta informasi telepon: nama operator dan jenis saluran, penanda virtual (VoIP) serta sekali pakai, dan penggunaan nomor duplikat di seluruh sesi Anda.\n\n**Cara pemeriksaan menemukan verifikasi.** Pencocokan dilakukan berdasarkan aplikasi Anda ditambah `phone_number` berformat E.164 — `request_id` bukan merupakan input. Verifikasi tertunda terbaru yang dibuat dalam **5 menit** terakhir akan diperiksa. Jika tidak ada (tidak pernah dikirim, sudah diselesaikan, atau lebih lama dari 5 menit), endpoint mengembalikan `200` dengan `status: \"Expired or Not Found\"`.\n\n**Batas percobaan.** Setiap verifikasi mengizinkan **3 percobaan kode**. Dua kode salah pertama mengembalikan `status: \"Failed\"` dengan sisa percobaan dan `phone: null`; kode salah ketiga menyelesaikan verifikasi sebagai `Declined` dengan peringatan `VERIFICATION_CODE_ATTEMPTS_EXCEEDED` dan mengembalikan laporan telepon lengkap.\n\n**Hasil.** `Approved` — kode benar dan tidak ada risiko penolakan. `Declined` — terminal: kode benar tetapi cocok dengan risiko penolakan (tindakan `DECLINE` di bawah, nomor dalam daftar blokir atau berisiko tinggi), atau batas percobaan telah habis. `Failed` — kode salah, masih ada sisa percobaan. `Expired or Not Found` — tidak ada yang perlu diperiksa. Pada `Approved`/`Declined`, `request_id` sama dengan `request_id` pengiriman (ID sesi) dan `phone` memuat laporan lengkap (`carrier`, `is_virtual`, `is_disposable`, `warnings`, `lifecycle`, `matches`); pada `Failed` dan `Expired or Not Found`, `request_id` berupa UUID acak sekali pakai.\n\n**Tindakan risiko.** `duplicated_phone_number_action`, `disposable_number_action`, dan `voip_number_action` menentukan apa yang terjadi ketika risiko terkait terdeteksi pada kode yang benar: `DECLINE` mengubah status akhir menjadi `Declined`; `NO_ACTION` (bawaan) mencatat risiko di `phone.warnings` tanpa memengaruhi status.\n\n**Penagihan.** Pemeriksaan gratis — pengiriman ditagihkan di sisi pengiriman (lihat [Harga Verifikasi Telepon](/id/getting-started/phone-verification-pricing)).\n\n**Persistensi sesi.** Pemeriksaan yang telah selesai akan memperbarui sesi yang dibuat oleh pengiriman (terlihat di Business Console, dapat ditanyakan melalui `GET /v3/session/{sessionId}/decision/`) dan memicu webhook `status.updated`.\n\n**Sandbox.** Kunci API sandbox melewati semua pemrosesan: kode apa pun dengan format yang valid (4–8 digit, termasuk `123456`) mengembalikan payload `Approved` statis dengan objek `phone` datar yang disederhanakan (`status`, `phone_number`, `country_code`, `carrier_name`, `line_type`, `flags`); input yang tidak valid tetap mengembalikan `400`. Tidak ada data yang disimpan.\n\n**Autentikasi.** Kirim kunci API aplikasi Anda di header `x-api-key`. Kredensial yang hilang atau tidak valid mengembalikan `403` (`{\"detail\": \"You do not have permission to perform this action.\"}`) — API ini tidak pernah mengembalikan `401`.\n\n**Batas laju.** Anggaran penulisan bersama sebesar 300 permintaan/menit per kunci API, ditambah batas anti-penyalahgunaan hulu sebesar 4 percobaan per nomor per jam; melampaui salah satunya akan mengembalikan `429`.\n\n**Jejak sosial.** Atur `enable_social` ke `true` untuk menambahkan blok `phone_social`: platform online tempat nomor ini terdaftar, dengan jumlah per kategori dan detail profil apa pun yang tersedia. `profiles_registered: 0` berarti platform telah diperiksa dan nomor tidak ditemukan di platform mana pun - jawaban yang valid dan dapat ditagih. Blok ini tidak ada jika pengaya tidak diminta atau pemeriksaan tidak dapat diselesaikan, dan tidak ditagihkan dalam kasus tersebut. Penagihan menambahkan satu unit `phone_social` per permintaan di luar harga endpoint ini sendiri.",
        "operationId": "post_v3phone_check",
        "x-didit-sdk": {
          "resource": "phone",
          "method": "check_code",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Standalone APIs"
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST https://verification.didit.me/v3/phone/check/ \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"phone_number\": \"+14155552671\",\n    \"code\": \"123456\",\n    \"voip_number_action\": \"DECLINE\"\n  }'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.phone.check_code(\n    phone_number=\"+14155552671\",\n    code=\"123456\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.phone.checkCode({\n  phone_number: \"+14155552671\",\n  code: \"123456\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Phone.CheckCode(ctx, didit.PhoneCheckCodeParams{\n\tPhoneNumber: \"+14155552671\",\n\tCode:        \"123456\",\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.PhoneCheckCodeParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.phone().checkCode(PhoneCheckCodeParams.builder()\n        .phoneNumber(\"+14155552671\")\n        .code(\"123456\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->phone->checkCode([\n    'phone_number' => '+14155552671',\n    'code' => '123456',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.phone.check_code(\n  phone_number: \"+14155552671\",\n  code: \"123456\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Phone.CheckCodeAsync(new PhoneCheckCodeParams\n{\n    PhoneNumber = \"+14155552671\",\n    Code = \"123456\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "phone_number": {
                    "type": "string",
                    "maxLength": 20,
                    "description": "Nomor telepon yang sama dengan yang digunakan dalam panggilan [`POST /v3/phone/send/`](/id/standalone-apis/phone-send) yang cocok, dalam format E.164. Ini yang menautkan pemeriksaan ke pengiriman.",
                    "example": "+14155552671"
                  },
                  "code": {
                    "type": "string",
                    "minLength": 4,
                    "maxLength": 8,
                    "pattern": "^[0-9]{4,8}$",
                    "description": "OTP yang diterima pengguna akhir. Harus terdiri dari 4–8 digit angka — selain itu akan mengembalikan `400` tanpa menghabiskan percobaan. Kode yang formatnya benar tetapi salah akan mengembalikan `200` dengan `status: \"Failed\"` dan menghabiskan salah satu dari 3 percobaan.",
                    "example": "123456"
                  },
                  "duplicated_phone_number_action": {
                    "type": "string",
                    "enum": [
                      "NO_ACTION",
                      "DECLINE"
                    ],
                    "default": "NO_ACTION",
                    "description": "Tindakan yang harus diambil ketika nomor yang sama telah digunakan oleh pengguna yang berbeda (`vendor_data` berbeda) dari aplikasi Anda. `DECLINE` mengubah `status` akhir menjadi `Declined`; `NO_ACTION` mencatat risiko dalam `phone.warnings` dan mengisi `phone.matches`."
                  },
                  "disposable_number_action": {
                    "type": "string",
                    "enum": [
                      "NO_ACTION",
                      "DECLINE"
                    ],
                    "default": "NO_ACTION",
                    "description": "Tindakan yang diambil saat pemeriksaan operator menandai nomor tersebut sebagai nomor sementara/sekali pakai (`phone.is_disposable`). `DECLINE` mengubah `status` akhir menjadi `Declined`; `NO_ACTION` mencatat risiko tersebut dalam `phone.warnings`."
                  },
                  "voip_number_action": {
                    "type": "string",
                    "enum": [
                      "NO_ACTION",
                      "DECLINE"
                    ],
                    "default": "NO_ACTION",
                    "description": "Tindakan yang diambil saat pencarian operator melaporkan jenis nomor virtual — `voip`, `isp`, atau `vpn` (`phone.is_virtual`). `DECLINE` mengubah `status` akhir menjadi `Declined`; `NO_ACTION` mencatat risiko tersebut dalam `phone.warnings`."
                  },
                  "enable_enrichment": {
                    "type": "boolean",
                    "default": false,
                    "description": "Jika `true`, jalankan juga intelijen telepon pada nomor tersebut: skor risiko, jenis saluran, apakah nomor baru saja di-porting, dan indeks kepercayaan. Ditagihkan sebagai satu unit `phone_intelligence_api` per permintaan ($0.05 pada harga terdaftar) di luar harga endpoint ini sendiri. Permintaan mengembalikan `403` jika saldo Anda tidak mencukupi.",
                    "example": false
                  },
                  "phone_intelligence_score_action": {
                    "type": "string",
                    "enum": [
                      "NO_ACTION",
                      "DECLINE"
                    ],
                    "default": "NO_ACTION",
                    "description": "Tindakan saat skor risiko intelijen telepon berada di atas ambang batas. `DECLINE` mengubah `status` akhir menjadi `Declined`; `NO_ACTION` mencatat sinyal tanpa menolak. Hanya berlaku saat `enable_enrichment` bernilai `true`."
                  },
                  "phone_type_risk_action": {
                    "type": "string",
                    "enum": [
                      "NO_ACTION",
                      "DECLINE"
                    ],
                    "default": "NO_ACTION",
                    "description": "Tindakan saat nomor telepon merupakan jenis saluran berisiko tinggi. `DECLINE` mengubah `status` akhir menjadi `Declined`; `NO_ACTION` mencatat sinyal tanpa menolak. Hanya berlaku saat `enable_enrichment` bernilai `true`."
                  },
                  "recent_port_action": {
                    "type": "string",
                    "enum": [
                      "NO_ACTION",
                      "DECLINE"
                    ],
                    "default": "NO_ACTION",
                    "description": "Tindakan saat nomor baru saja di-porting ke operator lain. `DECLINE` mengubah `status` akhir menjadi `Declined`; `NO_ACTION` mencatat sinyal tanpa menolak. Hanya berlaku saat `enable_enrichment` bernilai `true`."
                  },
                  "low_phone_trust_action": {
                    "type": "string",
                    "enum": [
                      "NO_ACTION",
                      "DECLINE"
                    ],
                    "default": "NO_ACTION",
                    "description": "Tindakan saat indeks kepercayaan intelijen telepon berada pada atau di bawah ambang batas. `DECLINE` mengubah `status` akhir menjadi `Declined`; `NO_ACTION` mencatat sinyal tanpa menolak. Hanya berlaku saat `enable_enrichment` bernilai `true`."
                  },
                  "enable_social": {
                    "type": "boolean",
                    "default": false,
                    "description": "Jika true, cari juga jejak sosial nomor tersebut - platform perpesanan, sosial, e-commerce, dan profesional tempat nomor tersebut terdaftar. Ditagih sebagai satu unit `phone_social` per permintaan selain harga endpoint ini sendiri.",
                    "example": true
                  },
                  "phone_no_social_presence_action": {
                    "type": "string",
                    "enum": [
                      "NO_ACTION",
                      "DECLINE"
                    ],
                    "default": "NO_ACTION",
                    "description": "Tindakan saat pemeriksaan jejak sosial mendapati nomor tidak terdaftar di platform mana pun yang dicakup. Hanya NO_ACTION dan DECLINE yang diterima pada endpoint ini; REVIEW tersedia pada kunci konfigurasi alur kerja dengan nama yang sama."
                  }
                },
                "required": [
                  "phone_number",
                  "code"
                ]
              },
              "examples": {
                "Default": {
                  "summary": "Catat semua risiko tetapi jangan pernah menolak otomatis",
                  "value": {
                    "phone_number": "+14155552671",
                    "code": "123456"
                  }
                },
                "Strict risk policy": {
                  "summary": "Tolak otomatis nomor VoIP dan sekali pakai",
                  "value": {
                    "phone_number": "+14155552671",
                    "code": "123456",
                    "voip_number_action": "DECLINE",
                    "disposable_number_action": "DECLINE"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Pemeriksaan selesai — kode yang salah dan verifikasi yang tidak ditemukan juga mengembalikan `200`; periksa `status`, bukan kode HTTP. `phone` hanya diisi pada hasil akhir (`Approved`/`Declined`), `null` pada `Failed`, dan tidak ada pada `Expired or Not Found`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PhoneVerificationCheckResponse"
                },
                "examples": {
                  "Approved": {
                    "summary": "Kode benar — laporan telepon lengkap dengan operator, siklus hidup, dan kecocokan",
                    "value": {
                      "request_id": "e39cb057-92fc-4b59-b84e-02fec29a0f24",
                      "status": "Approved",
                      "message": "The verification code is correct.",
                      "phone": {
                        "status": "Approved",
                        "phone_number_prefix": "+1",
                        "phone_number": "4155552671",
                        "full_number": "+14155552671",
                        "country_code": "US",
                        "country_name": "United States",
                        "carrier": {
                          "name": "AT&T",
                          "type": "mobile"
                        },
                        "is_disposable": false,
                        "is_virtual": false,
                        "verification_method": "whatsapp",
                        "verification_attempts": 1,
                        "verified_at": "2026-06-12T01:24:47.311323Z",
                        "warnings": [],
                        "lifecycle": [
                          {
                            "type": "PHONE_VERIFICATION_MESSAGE_SENT",
                            "timestamp": "2026-06-12T01:23:39.580554+00:00",
                            "details": {
                              "status": "Success",
                              "reason": null,
                              "channel": "whatsapp",
                              "actual_channel": "whatsapp"
                            },
                            "fee": 0.0509
                          },
                          {
                            "type": "PHONE_DELIVERY_DELIVERED",
                            "timestamp": "2026-06-12T01:23:43.118220+00:00",
                            "details": {
                              "channel": "whatsapp",
                              "status": "delivered"
                            },
                            "fee": 0
                          },
                          {
                            "type": "VALID_CODE_ENTERED",
                            "timestamp": "2026-06-12T01:24:47.311201+00:00",
                            "details": {
                              "code_tried": "123456",
                              "status": "Approved"
                            },
                            "fee": 0
                          },
                          {
                            "type": "PHONE_VERIFICATION_APPROVED",
                            "timestamp": "2026-06-12T01:24:47.384292+00:00",
                            "details": null,
                            "fee": 0
                          }
                        ],
                        "matches": []
                      },
                      "vendor_data": "user-1234",
                      "metadata": null,
                      "created_at": "2026-06-12T01:24:47.401719+00:00"
                    }
                  },
                  "Failed (attempts remaining)": {
                    "summary": "Kode salah — pengguna dapat mencoba lagi; request_id di sini adalah UUID satu kali pakai",
                    "value": {
                      "request_id": "11111111-2222-3333-4444-555555555555",
                      "status": "Failed",
                      "message": "The verification code is incorrect. Attempts remaining: 2",
                      "phone": null,
                      "vendor_data": "user-1234",
                      "metadata": null,
                      "created_at": "2026-06-12T01:24:21.512340+00:00"
                    }
                  },
                  "Declined (max attempts)": {
                    "summary": "Kode salah ketiga — verifikasi diselesaikan sebagai Ditolak",
                    "value": {
                      "request_id": "e39cb057-92fc-4b59-b84e-02fec29a0f24",
                      "status": "Declined",
                      "message": "The verification code is incorrect. Maximum attempts reached.",
                      "phone": {
                        "status": "Declined",
                        "phone_number_prefix": "+1",
                        "phone_number": "4155552671",
                        "full_number": "+14155552671",
                        "country_code": "US",
                        "country_name": "United States",
                        "carrier": {
                          "name": "AT&T",
                          "type": "mobile"
                        },
                        "is_disposable": false,
                        "is_virtual": false,
                        "verification_method": "whatsapp",
                        "verification_attempts": 1,
                        "verified_at": null,
                        "warnings": [
                          {
                            "feature": "PHONE",
                            "risk": "VERIFICATION_CODE_ATTEMPTS_EXCEEDED",
                            "additional_data": null,
                            "log_type": "error",
                            "short_description": "Verification code attempts exceeded",
                            "long_description": "The system detected that the phone number has exceeded the maximum number of verification code attempts."
                          }
                        ],
                        "lifecycle": [
                          {
                            "type": "PHONE_VERIFICATION_MESSAGE_SENT",
                            "timestamp": "2026-06-12T01:23:39.580554+00:00",
                            "details": {
                              "status": "Success",
                              "reason": null,
                              "channel": "whatsapp",
                              "actual_channel": "whatsapp"
                            },
                            "fee": 0.0509
                          },
                          {
                            "type": "INVALID_CODE_ENTERED",
                            "timestamp": "2026-06-12T01:24:01.118220+00:00",
                            "details": {
                              "code_tried": "111111",
                              "status": "Failed"
                            },
                            "fee": 0
                          },
                          {
                            "type": "INVALID_CODE_ENTERED",
                            "timestamp": "2026-06-12T01:24:21.512340+00:00",
                            "details": {
                              "code_tried": "222222",
                              "status": "Failed"
                            },
                            "fee": 0
                          },
                          {
                            "type": "INVALID_CODE_ENTERED",
                            "timestamp": "2026-06-12T01:24:47.311201+00:00",
                            "details": {
                              "code_tried": "333333",
                              "status": "Failed"
                            },
                            "fee": 0
                          },
                          {
                            "type": "PHONE_VERIFICATION_DECLINED",
                            "timestamp": "2026-06-12T01:24:47.384292+00:00",
                            "details": {
                              "reason": "VERIFICATION_CODE_ATTEMPTS_EXCEEDED"
                            },
                            "fee": 0
                          }
                        ],
                        "matches": []
                      },
                      "vendor_data": "user-1234",
                      "metadata": null,
                      "created_at": "2026-06-12T01:24:47.401719+00:00"
                    }
                  },
                  "Declined (risk policy)": {
                    "summary": "Kode benar, tetapi nomornya adalah nomor VoIP dan voip_number_action=DECLINE",
                    "value": {
                      "request_id": "7f1c9d2e-44a1-4b6e-9a3e-5b8e6f1c2d3a",
                      "status": "Declined",
                      "message": "The verification code is correct.",
                      "phone": {
                        "status": "Declined",
                        "phone_number_prefix": "+1",
                        "phone_number": "5005550006",
                        "full_number": "+15005550006",
                        "country_code": "US",
                        "country_name": "United States",
                        "carrier": {
                          "name": "CLEC LLC",
                          "type": "voip"
                        },
                        "is_disposable": false,
                        "is_virtual": true,
                        "verification_method": "sms",
                        "verification_attempts": 1,
                        "verified_at": "2026-06-12T01:24:47.311323Z",
                        "warnings": [
                          {
                            "feature": "PHONE",
                            "risk": "VOIP_NUMBER_DETECTED",
                            "additional_data": null,
                            "log_type": "error",
                            "short_description": "VoIP number detected",
                            "long_description": "The system detected that the phone number is a VoIP number, which is not allowed."
                          }
                        ],
                        "lifecycle": [
                          {
                            "type": "PHONE_VERIFICATION_MESSAGE_SENT",
                            "timestamp": "2026-06-12T01:23:39.580554+00:00",
                            "details": {
                              "status": "Success",
                              "reason": null,
                              "channel": "whatsapp",
                              "actual_channel": "sms"
                            },
                            "fee": 0.0509
                          },
                          {
                            "type": "VALID_CODE_ENTERED",
                            "timestamp": "2026-06-12T01:24:47.311201+00:00",
                            "details": {
                              "code_tried": "123456",
                              "status": "Approved"
                            },
                            "fee": 0
                          },
                          {
                            "type": "PHONE_VERIFICATION_DECLINED",
                            "timestamp": "2026-06-12T01:24:47.384292+00:00",
                            "details": {
                              "reason": "VOIP_NUMBER_DETECTED"
                            },
                            "fee": 0
                          }
                        ],
                        "matches": []
                      },
                      "vendor_data": "user-1234",
                      "metadata": null,
                      "created_at": "2026-06-12T01:24:47.401719+00:00"
                    }
                  },
                  "Expired or Not Found": {
                    "summary": "Tidak ada verifikasi tertunda untuk nomor ini dalam 5 menit terakhir",
                    "value": {
                      "request_id": "69cc35c6-280a-47a6-ab8c-4f32abc02ed0",
                      "status": "Expired or Not Found",
                      "message": "No pending phone verification found in the last 5 minutes.",
                      "vendor_data": null,
                      "metadata": null,
                      "created_at": "2026-06-12T01:24:47.311323+00:00"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Kesalahan validasi — envelope kesalahan kolom DRF: satu array pesan per kolom yang bermasalah.",
            "content": {
              "application/json": {
                "examples": {
                  "Invalid code format": {
                    "summary": "`code` bukan 4–8 digit numerik",
                    "value": {
                      "code": [
                        "Invalid code format. Enter 4 to 8 numeric digits."
                      ]
                    }
                  },
                  "Invalid phone number": {
                    "summary": "`phone_number` bukan format E.164 yang valid",
                    "value": {
                      "phone_number": [
                        "Invalid phone number provided."
                      ]
                    }
                  },
                  "Invalid action": {
                    "summary": "Tindakan risiko hanya menerima NO_ACTION atau DECLINE",
                    "value": {
                      "voip_number_action": [
                        "\"REVIEW\" is not a valid choice."
                      ]
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Izin ditolak. Dikembalikan ketika header `x-api-key` tidak ada; kunci yang salah, dicabut, atau kedaluwarsa mengembalikan `401`. Pemeriksaan ini gratis, sehingga tidak ada pemeriksaan kredit di sini.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing or invalid API key": {
                    "summary": "Tidak ada header `x-api-key`, atau kuncinya tidak valid/dicabut",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Batas laju terlampaui. Endpoint POST/PATCH/DELETE berbagi anggaran 300 permintaan penulisan per menit per kunci API (pembuatan transaksi dan ingesti event memiliki anggaran terpisah sebesar 600). Selain itu, batas atas anti-penyalahgunaan sebanyak 4 upaya verifikasi per nomor telepon per jam berlaku di sisi hulu. Respons menyertakan header `X-RateLimit-Limit`, `X-RateLimit-Remaining`, `X-RateLimit-Reset`, dan `Retry-After`. Catatan: header `X-RateLimit-*`/`Retry-After` hanya menyertai 429 batas penulisan 300/menit; 429 batas per nomor tidak menyertakan header batas laju.",
            "content": {
              "application/json": {
                "examples": {
                  "Per-number cap": {
                    "summary": "Lebih dari 4 upaya verifikasi untuk nomor yang sama dalam satu jam terakhir",
                    "value": {
                      "detail": "Maximum verification attempts reached for this phone number. Only 4 authentication attempts are allowed per hour. Try again later or use a different number."
                    }
                  },
                  "Write rate limit exceeded": {
                    "summary": "Lebih dari 300 permintaan tulis pada menit ini",
                    "value": {
                      "detail": "Write request rate limit exceeded. You can make up to 300 requests per minute."
                    }
                  }
                },
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "502": {
            "description": "Penyedia verifikasi telepon sementara tidak tersedia - respons 5xx, batas waktu habis (timeout), atau kegagalan koneksi yang tetap terjadi setelah coba lagi bawaan. Aman untuk dicoba lagi; kuota upaya tidak terpakai.",
            "content": {
              "application/json": {
                "examples": {
                  "Provider outage": {
                    "summary": "Penyedia tidak menjawab permintaan pemeriksaan",
                    "value": {
                      "detail": "Phone verification is temporarily unavailable. Please try again shortly.",
                      "code": "phone_provider_unavailable"
                    }
                  }
                },
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Kegagalan tak terduga saat memverifikasi kode di sistem upstream yang bukan merupakan gangguan penyedia yang sudah diketahui. Aman untuk dicoba lagi; kuota percobaan hanya terpakai oleh pemeriksaan yang selesai.",
            "content": {
              "application/json": {
                "examples": {
                  "Provider error": {
                    "summary": "Verifikasi kode tidak dapat diselesaikan",
                    "value": {
                      "detail": "Error checking phone verification"
                    }
                  }
                },
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/bank/account-check/": {
      "post": {
        "summary": "Periksa rekening bank",
        "description": "Periksa bahwa rekening bank milik orang atau perusahaan yang Anda sebutkan, sebelum Anda mengirim uang ke rekening tersebut. Tanpa sesi dan tanpa masuk: kirim nama dan rekening, baca hasilnya. Ini adalah [pemeriksaan rekening](/id/core-technology/bank-verification/account-check) dari langkah Verifikasi Bank, yang dijalankan dari backend Anda.\n\n**Yang Anda kirimkan.** `country` rekening (ISO 3166-1 alpha-3), `account` sesuai penulisan di negara tersebut, dan nama `holder`: `full_name` untuk perorangan atau `business_name` untuk perusahaan. Nama bisnis digunakan untuk memeriksa rekening bisnis.\n\n**Yang Anda terima kembali.** `result` adalah `match`, `close_match`, `no_match`, atau `cannot_verify`. Pada `close_match`, `holder_name` adalah nama yang tercatat pada rekening di bank tersebut, jika bank mengembalikannya. `account` dikembalikan disamarkan dengan hanya menyisakan 4 karakter terakhirnya.\n\n**Penagihan.** Setiap pemeriksaan yang dijawab oleh bank ditagih satu kali sesuai harga pemeriksaan rekening dari negara rekening tersebut, apa pun hasilnya: `no_match`, rekening yang tidak ada, dan `cannot_verify` juga ditagih. Permintaan yang dijawab dengan kesalahan tidak pernah ditagih.\n\n**Setiap permintaan adalah pemeriksaan baru.** Tidak ada kunci idempotensi dan tidak ada endpoint untuk membaca kembali pemeriksaan, sehingga permintaan yang dicoba lagi akan kembali dijalankan dan ditagih. Simpan responsnya.\n\n**Sandbox.** Gunakan kunci API sandbox dengan detail rekening sampel. Kunci sandbox tidak memanggil bank mana pun dan tidak dikenai biaya. 4 karakter terakhir dari IBAN, atau dari nomor rekening, menentukan jawabannya: `0001` menghasilkan `close_match` dengan `holder_name`, `0002` menghasilkan `close_match` tanpa nama, `0003` dan `0006` menghasilkan `no_match`, `0004` menghasilkan `cannot_verify`, `0005` menghasilkan `503`, dan `0009` menghasilkan `400`. Akhiran lainnya menghasilkan `match`.\n\n**Kunci API.** Kunci API dengan cakupan memerlukan akses tulis ke sesi.",
        "operationId": "post_v3_bank_account_check",
        "tags": [
          "Standalone APIs"
        ],
        "x-didit-sdk": {
          "resource": "bank",
          "method": "account_check",
          "auth": "api_key",
          "server": true
        },
        "security": [
          {
            "ApiKeyAuth": []
          },
          {
            "BearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BankAccountCheckRequest"
              },
              "examples": {
                "Person, Nigeria": {
                  "summary": "Kode bank dan nomor rekening, diperiksa terhadap nama individu",
                  "value": {
                    "country": "NGA",
                    "account": {
                      "bank_code": "000014",
                      "account_number": "0123450001"
                    },
                    "holder": {
                      "full_name": "Maria Oliveira"
                    },
                    "vendor_data": "payout_20481"
                  }
                },
                "Company, Nigeria": {
                  "summary": "Kode bank dan nomor rekening, diperiksa terhadap nama perusahaan",
                  "value": {
                    "country": "NGA",
                    "account": {
                      "bank_code": "000014",
                      "account_number": "0123456789"
                    },
                    "holder": {
                      "business_name": "Northwind Trading Ltd"
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Bank memberikan jawaban. Biaya pemeriksaan tetap dikenakan, apa pun hasilnya.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BankAccountCheckResponse"
                },
                "examples": {
                  "Close match": {
                    "summary": "Bank memiliki rekening atas nama yang mirip",
                    "value": {
                      "request_id": "c2f4a9e0-7b1d-4c3a-9e55-1d0a6b8f2a47",
                      "result": "close_match",
                      "holder_name": "MARIA R OLIVEIRA",
                      "account": "****0001",
                      "vendor_data": "payout_20481",
                      "created_at": "2026-10-21T14:32:08Z"
                    }
                  },
                  "Match": {
                    "summary": "Bank memiliki rekening atas nama yang dikirimkan",
                    "value": {
                      "request_id": "5b0e2d7c-41a8-4f6e-9c3b-8e7d1a2f6c90",
                      "result": "match",
                      "holder_name": null,
                      "account": "****6789",
                      "vendor_data": null,
                      "created_at": "2026-10-21T14:35:41Z"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Ditolak seperti yang dikirim, dan tidak ditagih. `field` menyebutkan kolom body yang perlu diperbaiki dan `reason` menjelaskan alasannya, dengan alasan yang sama seperti yang ditampilkan pada formulir akun yang di-hosting. Hanya kolom pertama yang ditolak yang dilaporkan.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BankAccountCheckError"
                },
                "examples": {
                  "Missing field": {
                    "summary": "Pemeriksaan di negara ini memerlukan kode bank",
                    "value": {
                      "detail": "The bank code is not valid (required).",
                      "code": "invalid_account_input",
                      "field": "account.bank_code",
                      "reason": "required"
                    }
                  },
                  "Invalid IBAN": {
                    "summary": "Panjang IBAN salah untuk negaranya",
                    "value": {
                      "detail": "The iban is not valid (length).",
                      "code": "invalid_account_input",
                      "field": "account.iban",
                      "reason": "length"
                    }
                  },
                  "Refused by the bank": {
                    "summary": "Bank menolak rekening seperti yang dikirim",
                    "value": {
                      "detail": "The account was refused as typed (rejected).",
                      "code": "invalid_account_input",
                      "field": "account.account_number",
                      "reason": "rejected"
                    }
                  },
                  "No name": {
                    "summary": "`holder` tidak memiliki `full_name` maupun `business_name`",
                    "value": {
                      "detail": "Send full_name for a person or business_name for a company.",
                      "code": "invalid_account_input",
                      "field": "holder",
                      "reason": "required"
                    }
                  },
                  "Consent required": {
                    "summary": "Pemeriksaan akun di negara ini memerlukan persetujuan pemilik akun",
                    "value": {
                      "detail": "Account checks in this country need the account holder's explicit consent. Ask for it, then send `consent=true`.",
                      "code": "invalid_account_input",
                      "field": "consent",
                      "reason": "required"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Kunci API dengan cakupan terbatas telah kedaluwarsa.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BankAccountCheckError"
                },
                "examples": {
                  "Expired key": {
                    "summary": "Tanggal kedaluwarsa kunci telah lewat",
                    "value": {
                      "detail": "This API key has expired."
                    }
                  }
                }
              }
            }
          },
          "402": {
            "description": "Pemeriksaan tidak dapat dibayar, sehingga tidak dijalankan. Isi saldo Anda, lalu kirimkan lagi.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BankAccountCheckError"
                },
                "examples": {
                  "Out of credit": {
                    "summary": "Saldo Anda tidak mencukupi untuk satu pemeriksaan",
                    "value": {
                      "detail": "You don't have enough credits to perform this request. Please top up at https://business.didit.me",
                      "code": "insufficient_credits"
                    }
                  },
                  "Not in your contract": {
                    "summary": "Kontrak Anda tidak memiliki harga untuk API pemeriksaan Akun",
                    "value": {
                      "detail": "Your contract does not price the Account check API. Contact your account manager.",
                      "code": "contract_rate_missing"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Header `x-api-key` atau token bearer tidak ada atau tidak valid, permintaan berasal dari alamat di luar daftar IP kunci, atau kunci dengan pembatasan cakupan tidak memiliki akses tulis ke sesi.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BankAccountCheckError"
                },
                "examples": {
                  "Missing or invalid credentials": {
                    "summary": "Tidak ada kunci API atau token yang valid",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "No sessions write": {
                    "summary": "Kunci dengan cakupan akses terbatas tanpa akses tulis ke sesi",
                    "value": {
                      "detail": "This API key has no write access to sessions."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Belum ada pemeriksaan akun yang melayani akun ini, sehingga tidak ada yang diperiksa atau ditagih. `country_not_covered`: tidak ada yang mencakup negaranya atau jenis akunnya (individu atau bisnis) di sana. `bank_not_covered`: tidak ada yang mencakup banknya.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BankAccountCheckError"
                },
                "examples": {
                  "Country not covered": {
                    "summary": "Tidak ada pemeriksaan akun yang mencakup negara tersebut",
                    "value": {
                      "detail": "No account check serves this country yet.",
                      "code": "country_not_covered"
                    }
                  },
                  "Bank not covered": {
                    "summary": "Tidak ada pemeriksaan akun yang mencakup bank akun tersebut",
                    "value": {
                      "detail": "No account check serves this account's bank yet.",
                      "code": "bank_not_covered"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimitedWrite"
          },
          "503": {
            "description": "Bank tidak dapat memberikan jawaban. Tidak ada yang diperiksa atau ditagih; kirim ulang pemeriksaan nanti.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BankAccountCheckError"
                },
                "examples": {
                  "Unavailable": {
                    "summary": "Bank tidak memberikan jawaban",
                    "value": {
                      "detail": "The account check is temporarily unavailable and this request was not charged. Please try again.",
                      "code": "account_check_unavailable"
                    }
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST https://verification.didit.me/v3/bank/account-check/ \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"country\": \"NGA\",\n    \"account\": {\"bank_code\": \"000014\", \"account_number\": \"0123450001\"},\n    \"holder\": {\"full_name\": \"Maria Oliveira\"},\n    \"vendor_data\": \"payout_20481\"\n  }'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.bank.account_check(\n    country=\"NGA\",\n    account={\n        \"account_number\": \"0123450001\",\n        \"bank_code\": \"000014\",\n    },\n    holder={\n        \"full_name\": \"Maria Oliveira\",\n    },\n    vendor_data=\"payout_20481\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.bank.accountCheck({\n  country: \"NGA\",\n  account: {\n    account_number: \"0123450001\",\n    bank_code: \"000014\",\n  },\n  holder: {\n    full_name: \"Maria Oliveira\",\n  },\n  vendor_data: \"payout_20481\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Bank.AccountCheck(ctx, didit.BankAccountCheckRequest{\n\tCountry: \"NGA\",\n\tAccount: didit.BankAccountCheckRequestAccount{\n\t\tAccountNumber: didit.String(\"0123450001\"),\n\t\tBankCode:      didit.String(\"000014\"),\n\t},\n\tHolder: didit.BankAccountCheckHolder{\n\t\tFullName: didit.String(\"Maria Oliveira\"),\n\t},\n\tVendorData: didit.String(\"payout_20481\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.BankAccountCheckHolder;\nimport me.didit.types.BankAccountCheckPersonHolder;\nimport me.didit.types.BankAccountCheckRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.bank().accountCheck(BankAccountCheckRequest.builder()\n        .country(\"NGA\")\n        .account(BankAccountCheckRequest.Account.builder()\n                .accountNumber(\"0123450001\")\n                .bankCode(\"000014\")\n                .build())\n        .holder(BankAccountCheckHolder.ofBankAccountCheckPersonHolder(BankAccountCheckPersonHolder.builder()\n                .fullName(\"Maria Oliveira\")\n                .build()))\n        .vendorData(\"payout_20481\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->bank->accountCheck([\n    'country' => 'NGA',\n    'account' => [\n        'account_number' => '0123450001',\n        'bank_code' => '000014',\n    ],\n    'holder' => [\n        'full_name' => 'Maria Oliveira',\n    ],\n    'vendor_data' => 'payout_20481',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.bank.account_check(\n  country: \"NGA\",\n  account: {\n    account_number: \"0123450001\",\n    bank_code: \"000014\",\n  },\n  holder: {\n    full_name: \"Maria Oliveira\",\n  },\n  vendor_data: \"payout_20481\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Bank.AccountCheckAsync(new BankAccountCheckRequest\n{\n    Country = \"NGA\",\n    Account = new()\n    {\n        AccountNumber = \"0123450001\",\n        BankCode = \"000014\",\n    },\n    Holder = new()\n    {\n        FullName = \"Maria Oliveira\",\n    },\n    VendorData = \"payout_20481\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/email/send/": {
      "post": {
        "summary": "Kirim Kode Email",
        "description": "Kirim kode sekali pakai (OTP) ke alamat email, lalu verifikasi dengan [`POST /v3/email/check/`](/id/standalone-apis/email-check).\n\n**Cara kerja pasangan pengiriman dan pemeriksaan.** Status verifikasi dikaitkan berdasarkan aplikasi Anda ditambah alamat `email` — pemanggilan periksa tidak memerlukan `request_id`. Setiap pengiriman baru membuat verifikasi tertunda yang berlaku selama **5 menit**: panggil periksa dengan alamat yang sama dan kode yang diterima pengguna sebelum batas waktu berakhir. Memanggil pengiriman lagi untuk alamat yang sama saat verifikasi masih tertunda akan menghasilkan kode baru untuk verifikasi yang sama tersebut (`status: \"Retry\"`, `request_id` yang sama); kode sebelumnya tidak lagi berfungsi. Paling banyak satu coba lagi yang dilampirkan dengan cara ini (total dua pengiriman); pengiriman berikutnya akan memulai verifikasi baru dengan `request_id` baru. Batas waktu 5 menit dihitung dari pengiriman pertama dan tidak diperpanjang oleh coba lagi.\n\n**Pra-pemeriksaan keterkiriman.** Sebelum apa pun dikirim, alamat melewati validasi sintaks dan DNS/MX. Alamat yang tidak dapat menerima email mengembalikan `200` dengan `status: \"Undeliverable\"` dan `reason: \"email_can_not_be_delivered\"` — tidak ada email yang dikirim, tidak ada biaya yang ditagihkan, dan verifikasi segera diselesaikan sebagai `Declined` (pemeriksaan lanjutan mengembalikan `Expired or Not Found`). Pengiriman yang gagal karena alasan selain alamat (email tidak dapat diserahkan untuk pengiriman) mengembalikan `503`: tidak ada kode yang dikirim, tidak ada biaya yang ditagihkan, verifikasi tetap terbuka, dan permintaan yang sama dapat diulang kembali.\n\n**Format kode dan branding.** Kode terdiri dari 4–8 karakter (`options.code_size`, default 6), berupa angka secara default; atur `options.alphanumeric_code: true` untuk huruf besar dan angka (perbandingan saat periksa tidak membedakan huruf besar/kecil). Templat email dilokalkan melalui `options.locale` (54 bahasa yang didukung) dan dapat menggunakan branding White Label aplikasi Anda melalui `options.use_white_label_customization`.\n\n**Penagihan.** Satu kredit API Verifikasi Email per pengiriman yang berhasil (`status: \"Success\"`), ditagihkan pada saat pengiriman. Pengiriman `Retry` dan `Undeliverable` gratis, dan pemeriksaan gratis.\n\n**Persistensi sesi.** Setiap verifikasi baru disimpan secara persisten sebagai sesi bertipe API: `request_id` adalah id sesi nyata yang dapat Anda teruskan ke `GET /v3/session/{sessionId}/decision/`, verifikasi muncul di Business Console, dan webhook `status.updated` terpicu seiring perkembangannya.\n\n**Sandbox.** Kunci API sandbox melewati pengiriman dan penagihan: setelah validasi permintaan (input yang salah format tetap mengembalikan `400`), endpoint mengembalikan payload `Success` statis dengan `request_id` acak; tidak ada email yang dikirim dan tidak ada yang disimpan secara persisten. Gunakan kode `123456` pada pemeriksaan sandbox.\n\n**Autentikasi.** Kirim kunci API aplikasi Anda di header `x-api-key`. Kredensial yang hilang atau tidak valid mengembalikan `403` (`{\"detail\": \"You do not have permission to perform this action.\"}`) — API ini tidak pernah mengembalikan `401`.\n\n**Batas laju.** Kuota bersama untuk permintaan tulis sebesar 300 permintaan/menit per kunci API di seluruh endpoint POST/PATCH/DELETE; melebihi batas ini mengembalikan `429`.",
        "operationId": "post_v3email_send",
        "x-didit-sdk": {
          "resource": "email",
          "method": "send_code",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Standalone APIs"
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST https://verification.didit.me/v3/email/send/ \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"email\": \"alice@example.com\",\n    \"options\": { \"code_size\": 6, \"locale\": \"en\" },\n    \"vendor_data\": \"user-1234\"\n  }'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.email.send_code(\n    email=\"alice@example.com\",\n    options={\n        \"locale\": \"en\",\n    },\n    vendor_data=\"user-1234\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.email.sendCode({\n  email: \"alice@example.com\",\n  options: {\n    locale: \"en\",\n  },\n  vendor_data: \"user-1234\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Email.SendCode(ctx, didit.EmailSendCodeParams{\n\tEmail: \"alice@example.com\",\n\tOptions: didit.Some(didit.EmailSendCodeParamsOptions{\n\t\tLocale: didit.Some(didit.EmailSendCodeParamsOptionsLocale(\"en\")),\n\t}),\n\tVendorData: didit.String(\"user-1234\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.EmailSendCodeParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.email().sendCode(EmailSendCodeParams.builder()\n        .email(\"alice@example.com\")\n        .options(EmailSendCodeParams.Options.builder()\n                .locale(EmailSendCodeParams.Options.Locale.of(\"en\"))\n                .build())\n        .vendorData(\"user-1234\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->email->sendCode([\n    'email' => 'alice@example.com',\n    'options' => [\n        'locale' => 'en',\n    ],\n    'vendor_data' => 'user-1234',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.email.send_code(\n  email: \"alice@example.com\",\n  options: {\n    locale: \"en\",\n  },\n  vendor_data: \"user-1234\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Email.SendCodeAsync(new EmailSendCodeParams\n{\n    Email = \"alice@example.com\",\n    Options = new EmailSendCodeParamsOptions\n    {\n        Locale = new EmailSendCodeParamsOptionsLocale(\"en\"),\n    },\n    VendorData = \"user-1234\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "email": {
                    "type": "string",
                    "format": "email",
                    "description": "Alamat email penerima. Alamat dengan format yang salah mengembalikan `400`; alamat dengan sintaks yang valid tetapi tidak dapat menerima email (validasi DNS/MX gagal) mengembalikan `200` dengan `status: \"Undeliverable\"`.",
                    "example": "alice@example.com"
                  },
                  "options": {
                    "type": "object",
                    "description": "Opsi format, lokalisasi, dan branding OTP. Semua kolom bersifat opsional.",
                    "properties": {
                      "code_size": {
                        "type": "integer",
                        "minimum": 4,
                        "maximum": 8,
                        "default": 6,
                        "description": "Jumlah karakter dalam OTP (secara default berupa digit; huruf besar dan digit ketika `alphanumeric_code` bernilai `true`)."
                      },
                      "alphanumeric_code": {
                        "type": "boolean",
                        "default": false,
                        "description": "Jika `true`, OTP terdiri dari huruf besar `A–Z` dan angka `0–9`, bukan hanya angka. Perbandingan `/v3/email/check/` bersifat tidak peka huruf besar/kecil."
                      },
                      "locale": {
                        "type": "string",
                        "maxLength": 5,
                        "enum": [
                          "en",
                          "ar",
                          "bn",
                          "bg",
                          "bs",
                          "ca",
                          "cs",
                          "da",
                          "de",
                          "el",
                          "es",
                          "et",
                          "fa",
                          "fi",
                          "fr",
                          "he",
                          "hi",
                          "hr",
                          "hu",
                          "hy",
                          "id",
                          "it",
                          "ja",
                          "ka",
                          "kk",
                          "ko",
                          "ky",
                          "lt",
                          "lv",
                          "cnr",
                          "mk",
                          "mn",
                          "ms",
                          "nl",
                          "no",
                          "pl",
                          "pt-BR",
                          "pt",
                          "ro",
                          "ru",
                          "sk",
                          "sl",
                          "so",
                          "sq",
                          "sr",
                          "sv",
                          "th",
                          "tr",
                          "uk",
                          "uz",
                          "vi",
                          "zh-CN",
                          "zh-TW",
                          "zh"
                        ],
                        "description": "Bahasa templat email OTP. Default adalah `en`. Nilai yang tidak didukung mengembalikan `400` yang mencantumkan semua lokal yang didukung.",
                        "example": "en"
                      },
                      "use_white_label_customization": {
                        "type": "boolean",
                        "default": false,
                        "description": "Jika `true`, email OTP menggunakan kustomisasi White Label aplikasi Anda (logo, warna, branding pengirim) alih-alih templat default Didit."
                      }
                    }
                  },
                  "signals": {
                    "type": "object",
                    "description": "Sinyal perangkat dan jaringan opsional mengenai pengguna akhir, yang diteruskan ke lapisan anti-fraud untuk meningkatkan deteksi lalu lintas yang menyalahgunakan sistem atau dihasilkan secara otomatis. Semua kolom bersifat opsional.",
                    "properties": {
                      "ip": {
                        "type": "string",
                        "description": "Alamat IP perangkat pengguna akhir. IPv4 atau IPv6.",
                        "example": "192.0.2.1"
                      },
                      "device_id": {
                        "type": "string",
                        "maxLength": 255,
                        "description": "Pengenal unik perangkat pengguna akhir. Android: `ANDROID_ID`; iOS: `identifierForVendor`.",
                        "example": "8F0B8FDD-C2CB-4387-B20A-56E9B2E5A0D2"
                      },
                      "device_platform": {
                        "type": "string",
                        "enum": [
                          "android",
                          "ios",
                          "ipados",
                          "tvos",
                          "web"
                        ],
                        "description": "Platform perangkat pengguna akhir."
                      },
                      "device_model": {
                        "type": "string",
                        "maxLength": 255,
                        "description": "Model perangkat pengguna akhir.",
                        "example": "iPhone17,2"
                      },
                      "os_version": {
                        "type": "string",
                        "maxLength": 64,
                        "description": "Versi sistem operasi dari perangkat pengguna akhir.",
                        "example": "18.0.1"
                      },
                      "app_version": {
                        "type": "string",
                        "maxLength": 64,
                        "description": "Versi aplikasi Anda.",
                        "example": "1.2.34"
                      },
                      "user_agent": {
                        "type": "string",
                        "maxLength": 512,
                        "description": "User agent dari browser atau aplikasi pengguna akhir.",
                        "example": "Mozilla/5.0 (iPhone; CPU iPhone OS 14_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0.3 Mobile/15E148 Safari/604.1"
                      }
                    }
                  },
                  "vendor_data": {
                    "type": "string",
                    "description": "Pengidentifikasi opsional yang dikontrol pemanggil (id pengguna internal Anda, email, UUID, dll.) yang disimpan pada sesi dan dikembalikan dalam respons pengiriman, respons pemeriksaan kecocokan, webhook, dan Business Console. Gunakan ini untuk menghubungkan `request_id` Didit dengan data pengguna Anda."
                  },
                  "metadata": {
                    "type": "object",
                    "nullable": true,
                    "description": "Objek JSON bentuk bebas opsional yang disimpan pada sesi dan dikembalikan dalam respons pengiriman, respons pemeriksaan pencocokan, webhook, dan Business Console."
                  }
                },
                "required": [
                  "email"
                ]
              },
              "examples": {
                "Numeric 6-digit code": {
                  "summary": "Default — kode numerik 6 digit dalam bahasa Inggris",
                  "value": {
                    "email": "alice@example.com",
                    "options": {
                      "locale": "en"
                    },
                    "vendor_data": "user-1234"
                  }
                },
                "Alphanumeric 8-character code": {
                  "summary": "Huruf besar + digit, templat Spanyol",
                  "value": {
                    "email": "bob@example.com",
                    "options": {
                      "code_size": 8,
                      "alphanumeric_code": true,
                      "locale": "es"
                    }
                  }
                },
                "White-label branding": {
                  "summary": "Kirim email OTP dengan kustomisasi White Label aplikasi Anda",
                  "value": {
                    "email": "carol@example.com",
                    "options": {
                      "locale": "en",
                      "use_white_label_customization": true
                    },
                    "vendor_data": "user-5678"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Pengiriman dikonfirmasi. Periksa `status`: `Success` dan `Retry` berarti kode sedang dikirim; `Undeliverable` berarti alamat tidak dapat menerima surat dan verifikasi telah difinalisasi sebagai `Declined`. `request_id` adalah id sesi yang disimpan (id yang sama pada `Retry`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EmailVerificationSendResponse"
                },
                "examples": {
                  "Success": {
                    "summary": "OTP dikirimkan melalui email untuk verifikasi baru (ditagih)",
                    "value": {
                      "request_id": "e39cb057-92fc-4b59-b84e-02fec29a0f24",
                      "status": "Success",
                      "reason": null,
                      "vendor_data": "user-1234",
                      "metadata": null
                    }
                  },
                  "Retry": {
                    "summary": "Pengiriman kedua dalam jendela 5 menit — kode baru, request_id yang sama, gratis",
                    "value": {
                      "request_id": "e39cb057-92fc-4b59-b84e-02fec29a0f24",
                      "status": "Retry",
                      "reason": null,
                      "vendor_data": "user-1234",
                      "metadata": null
                    }
                  },
                  "Undeliverable": {
                    "summary": "Alamat gagal validasi DNS/MX — verifikasi diselesaikan dengan status Ditolak, tidak ada tagihan",
                    "value": {
                      "request_id": "cb1a5011-344d-444d-bdce-218904745d7f",
                      "status": "Undeliverable",
                      "reason": "email_can_not_be_delivered",
                      "vendor_data": "user-1234",
                      "metadata": null
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Kesalahan validasi — envelope kesalahan kolom DRF: satu array pesan per kolom yang bermasalah, bersarang di bawah `options` untuk kesalahan opsi.",
            "content": {
              "application/json": {
                "examples": {
                  "Invalid email": {
                    "summary": "Alamat email salah format",
                    "value": {
                      "email": [
                        "Enter a valid email address."
                      ]
                    }
                  },
                  "Unsupported locale": {
                    "summary": "`options.locale` berada di luar set yang didukung",
                    "value": {
                      "options": {
                        "locale": [
                          "Invalid locale. Supported locales are en, ar, bn, bg, bs, ca, cs, da, de, el, es, et, fa, fi, fr, he, hi, hr, hu, hy, id, it, ja, ka, kk, ko, ky, lt, lv, cnr, mk, mn, ms, nl, no, pl, pt-BR, pt, ro, ru, sk, sl, so, sq, sr, sv, th, tr, uk, uz, vi, zh-CN, zh-TW, zh."
                        ]
                      }
                    }
                  },
                  "Code size out of range": {
                    "summary": "`options.code_size` berada di luar rentang 4–8",
                    "value": {
                      "options": {
                        "code_size": [
                          "Ensure this value is less than or equal to 8."
                        ]
                      }
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Izin ditolak. Dikembalikan ketika header `x-api-key` tidak ada (`{\"detail\": ...}`); kunci yang salah, dicabut, atau kedaluwarsa mengembalikan `401`. Juga dikembalikan sebelum pengiriman apa pun ketika saldo organisasi tidak dapat mencukupi biaya satu kredit API Verifikasi Email (`{\"error\": ...}`).",
            "content": {
              "application/json": {
                "examples": {
                  "Missing or invalid API key": {
                    "summary": "Tidak ada header `x-api-key`, atau kuncinya tidak valid/dicabut",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Not enough credits": {
                    "summary": "Saldo organisasi tidak mencukupi untuk harga pengiriman",
                    "value": {
                      "error": "You don't have enough credits to perform this request."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Batas laju terlampaui. Endpoint POST/PATCH/DELETE berbagi anggaran 300 permintaan penulisan per menit per kunci API (pembuatan transaksi dan ingesti event memiliki anggaran terpisah sebesar 600). Respons menyertakan header `X-RateLimit-Limit`, `X-RateLimit-Remaining`, `X-RateLimit-Reset`, dan `Retry-After`.",
            "content": {
              "application/json": {
                "examples": {
                  "Write rate limit exceeded": {
                    "summary": "Lebih dari 300 permintaan tulis pada menit ini",
                    "value": {
                      "detail": "Write request rate limit exceeded. You can make up to 300 requests per minute."
                    }
                  }
                },
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "503": {
            "description": "Email tidak dapat dikirim karena alasan yang tidak terkait dengan alamat tersebut (penyedia email tidak dapat dihubungi, waktu habis, atau menolak pengiriman itu sendiri), sehingga tidak ada kode yang dikirim dan tidak ada yang ditagihkan atau dihitung sebagai upaya pengiriman. Ulangi permintaan yang sama.",
            "content": {
              "application/json": {
                "examples": {
                  "Email delivery unavailable": {
                    "summary": "Penyedia email gagal setelah satu kali coba lagi otomatis",
                    "value": {
                      "detail": "Email delivery is temporarily unavailable. Please try again."
                    }
                  }
                },
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/email/check/": {
      "post": {
        "summary": "Periksa Kode Email",
        "description": "Verifikasi OTP yang dikirimkan oleh [`POST /v3/email/send/`](/id/standalone-apis/email-send) dan dapatkan hasil verifikasi akhir beserta intelijen email: keterkiriman, paparan kebocoran data (`is_breached` dan daftar `breaches` dari database intelijen kebocoran data), deteksi penyedia email sekali pakai, dan penggunaan ganda alamat tersebut di seluruh sesi Anda.\n\n**Cara pemeriksaan menemukan verifikasi.** Pencocokan dilakukan berdasarkan aplikasi Anda ditambah alamat `email` — `request_id` bukan merupakan input. Verifikasi tertunda terbaru yang dibuat dalam **5 menit** terakhir akan diperiksa. Jika tidak ada (tidak pernah dikirim, sudah diselesaikan, tidak dapat dikirim saat pengiriman, atau lebih dari 5 menit), endpoint mengembalikan `200` dengan `status: \"Expired or Not Found\"`.\n\n**Batas percobaan.** Setiap verifikasi mengizinkan **3 kali percobaan kode**. Dua kode salah pertama mengembalikan `status: \"Failed\"` dengan sisa percobaan dan `email: null`; kode salah ketiga menyelesaikan verifikasi sebagai `Declined` dengan peringatan `EMAIL_CODE_ATTEMPTS_EXCEEDED` dan mengembalikan laporan email lengkap. Kode dibandingkan secara tidak peka huruf besar/kecil (relevan untuk pengiriman `alphanumeric_code`); hanya kode yang paling baru dikirim yang valid.\n\n**Hasil.** `Approved` — kode benar dan tidak ada risiko penolakan. `Declined` — terminal: kode benar tetapi cocok dengan risiko penolakan (tindakan `DECLINE` di bawah, alamat yang masuk daftar blokir, atau alamat ditemukan tidak dapat dikirim saat finalisasi), atau batas percobaan telah habis. `Failed` — kode salah, masih ada sisa percobaan. `Expired or Not Found` — tidak ada yang perlu diperiksa. Pada `Approved`/`Declined`, `request_id` sama dengan `request_id` pengiriman (id sesi) dan `email` memuat laporan lengkap (`is_breached`, `breaches`, `is_disposable`, `is_undeliverable`, `warnings`, `lifecycle`, `matches`); pada `Failed` dan `Expired or Not Found`, `request_id` berupa UUID acak sekali pakai.\n\n**Tindakan risiko.** `duplicated_email_action`, `breached_email_action`, dan `disposable_email_action` menentukan apa yang terjadi ketika risiko terkait terdeteksi pada kode yang benar: `DECLINE` mengubah status akhir menjadi `Declined`; `NO_ACTION` (default) mencatat risiko dalam `email.warnings` tanpa memengaruhi status.\n\n**Penagihan.** Pemeriksaan gratis — kredit digunakan saat pengiriman berhasil.\n\n**Persistensi sesi.** Pemeriksaan yang telah selesai akan memperbarui sesi yang dibuat oleh pengiriman (terlihat di Business Console, dapat diperiksa melalui `GET /v3/session/{sessionId}/decision/`) dan memicu webhook `status.updated`.\n\n**Sandbox.** Kunci API sandbox melewati semua pemrosesan: kode apa pun dengan format yang benar (termasuk `123456`) mengembalikan payload statis `Approved` dengan objek `email` yang disederhanakan (`status`, `email`, `is_breached`, `is_disposable`, `is_undeliverable`); input dengan format salah tetap mengembalikan `400`. Tidak ada data yang disimpan.\n\n**Autentikasi.** Kirim kunci API aplikasi Anda di header `x-api-key`. Kredensial yang hilang atau tidak valid mengembalikan `403` (`{\"detail\": \"You do not have permission to perform this action.\"}`) — API ini tidak pernah mengembalikan `401`.\n\n**Batas laju.** Kuota penulisan bersama sebesar 300 permintaan/menit per kunci API di seluruh endpoint POST/PATCH/DELETE; melebihi batas ini akan mengembalikan `429`.\n\n**Jejak sosial.** Atur `enable_social` ke `true` untuk menambahkan blok `email_social`: platform online tempat alamat ini terdaftar, beserta jumlah per kategori dan detail profil apa pun yang tersedia. `profiles_registered: 0` berarti platform telah diperiksa dan alamat tersebut tidak ditemukan di platform mana pun - jawaban yang valid dan dapat ditagih. Blok ini tidak ada jika add-on tidak diminta atau pemeriksaan tidak dapat diselesaikan, dan tidak ditagih dalam kasus tersebut. Penagihan menambahkan satu unit `email_social` per permintaan di luar harga endpoint ini sendiri.",
        "operationId": "post_v3email_check",
        "x-didit-sdk": {
          "resource": "email",
          "method": "check_code",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Standalone APIs"
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST https://verification.didit.me/v3/email/check/ \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"email\": \"alice@example.com\",\n    \"code\": \"123456\",\n    \"disposable_email_action\": \"DECLINE\"\n  }'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.email.check_code(\n    email=\"alice@example.com\",\n    code=\"123456\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.email.checkCode({\n  email: \"alice@example.com\",\n  code: \"123456\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Email.CheckCode(ctx, didit.EmailCheckCodeParams{\n\tEmail: \"alice@example.com\",\n\tCode:  \"123456\",\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.EmailCheckCodeParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.email().checkCode(EmailCheckCodeParams.builder()\n        .email(\"alice@example.com\")\n        .code(\"123456\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->email->checkCode([\n    'email' => 'alice@example.com',\n    'code' => '123456',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.email.check_code(\n  email: \"alice@example.com\",\n  code: \"123456\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Email.CheckCodeAsync(new EmailCheckCodeParams\n{\n    Email = \"alice@example.com\",\n    Code = \"123456\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "email": {
                    "type": "string",
                    "format": "email",
                    "description": "Alamat email yang sama dengan yang digunakan dalam panggilan [`POST /v3/email/send/`](/id/standalone-apis/email-send) yang cocok. Ini yang menautkan pemeriksaan ke pengiriman.",
                    "example": "alice@example.com"
                  },
                  "code": {
                    "type": "string",
                    "maxLength": 10,
                    "description": "OTP yang diterima pengguna akhir: 4–8 digit, atau 4–8 huruf/angka jika `alphanumeric_code: true` digunakan saat pengiriman. Perbandingan tidak peka huruf besar/kecil.",
                    "example": "123456"
                  },
                  "duplicated_email_action": {
                    "type": "string",
                    "enum": [
                      "NO_ACTION",
                      "DECLINE"
                    ],
                    "default": "NO_ACTION",
                    "description": "Tindakan yang harus diambil ketika alamat yang sama telah digunakan dan disetujui oleh pengguna yang berbeda (hanya verifikasi yang disetujui sebelumnya yang dihitung) (`vendor_data` berbeda) dari aplikasi Anda. `DECLINE` mengubah `status` akhir menjadi `Declined`; `NO_ACTION` mencatat risiko dalam `email.warnings` dan mengisi `email.matches`."
                  },
                  "breached_email_action": {
                    "type": "string",
                    "enum": [
                      "NO_ACTION",
                      "DECLINE"
                    ],
                    "default": "NO_ACTION",
                    "description": "Tindakan yang diambil saat alamat muncul dalam kebocoran data yang diketahui (`email.is_breached`). `DECLINE` mengubah `status` akhir menjadi `Declined`; `NO_ACTION` mencatat risiko tersebut dalam `email.warnings`."
                  },
                  "disposable_email_action": {
                    "type": "string",
                    "enum": [
                      "NO_ACTION",
                      "DECLINE"
                    ],
                    "default": "NO_ACTION",
                    "description": "Tindakan yang harus diambil ketika domain milik penyedia email sekali pakai/sementara (`email.is_disposable`). `DECLINE` mengubah `status` akhir menjadi `Declined`; `NO_ACTION` mencatat risiko dalam `email.warnings`."
                  },
                  "enable_enrichment": {
                    "type": "boolean",
                    "default": false,
                    "description": "Jika `true`, jalankan juga intelijen email pada alamat tersebut: skor risiko dan riwayat kebocorannya. Ditagihkan sebagai satu unit `email_intelligence_api` per permintaan ($0.05 pada harga terdaftar) di luar harga endpoint ini sendiri. Permintaan mengembalikan `403` jika saldo Anda tidak mencukupi.",
                    "example": false
                  },
                  "email_intelligence_score_action": {
                    "type": "string",
                    "enum": [
                      "NO_ACTION",
                      "DECLINE"
                    ],
                    "default": "NO_ACTION",
                    "description": "Tindakan saat skor risiko intelijen email berada di atas ambang batas. `DECLINE` mengubah `status` akhir menjadi `Declined`; `NO_ACTION` mencatat sinyal tanpa menolak. Hanya berlaku saat `enable_enrichment` bernilai `true`."
                  },
                  "recent_email_breach_action": {
                    "type": "string",
                    "enum": [
                      "NO_ACTION",
                      "DECLINE"
                    ],
                    "default": "NO_ACTION",
                    "description": "Tindakan saat alamat muncul dalam kebocoran data terkini yang diketahui. `DECLINE` mengubah `status` akhir menjadi `Declined`; `NO_ACTION` mencatat sinyal tanpa menolak. Hanya berlaku saat `enable_enrichment` bernilai `true`."
                  },
                  "frequent_email_breach_action": {
                    "type": "string",
                    "enum": [
                      "NO_ACTION",
                      "DECLINE"
                    ],
                    "default": "NO_ACTION",
                    "description": "Tindakan saat alamat muncul dalam banyak kebocoran data yang diketahui. `DECLINE` mengubah `status` akhir menjadi `Declined`; `NO_ACTION` mencatat sinyal tanpa menolak. Hanya berlaku saat `enable_enrichment` bernilai `true`."
                  },
                  "enable_social": {
                    "type": "boolean",
                    "default": false,
                    "description": "Jika true, cari juga jejak sosial alamat tersebut - platform email, sosial, profesional, e-commerce, dan hiburan tempat alamat tersebut terdaftar. Ditagih sebagai satu unit `email_social` per permintaan selain harga endpoint ini sendiri.",
                    "example": true
                  },
                  "email_no_social_presence_action": {
                    "type": "string",
                    "enum": [
                      "NO_ACTION",
                      "DECLINE"
                    ],
                    "default": "NO_ACTION",
                    "description": "Tindakan saat pemeriksaan jejak sosial mendapati alamat tidak terdaftar di platform mana pun yang dicakup. Hanya NO_ACTION dan DECLINE yang diterima pada endpoint ini; REVIEW tersedia pada kunci konfigurasi alur kerja dengan nama yang sama."
                  }
                },
                "required": [
                  "email",
                  "code"
                ]
              },
              "examples": {
                "Default": {
                  "summary": "Catat semua risiko tetapi jangan pernah menolak otomatis",
                  "value": {
                    "email": "alice@example.com",
                    "code": "123456"
                  }
                },
                "Strict risk policy": {
                  "summary": "Tolak otomatis kotak masuk sekali pakai dan yang mengalami kebocoran data",
                  "value": {
                    "email": "alice@example.com",
                    "code": "123456",
                    "disposable_email_action": "DECLINE",
                    "breached_email_action": "DECLINE"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Pemeriksaan selesai — kode yang salah dan verifikasi yang tidak ditemukan juga mengembalikan `200`; periksa `status`, bukan kode HTTP. `email` hanya diisi pada hasil akhir (`Approved`/`Declined`), `null` pada `Failed`, dan tidak ada pada `Expired or Not Found`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EmailVerificationCheckResponse"
                },
                "examples": {
                  "Approved": {
                    "summary": "Kode benar — alamat bersih, laporan email lengkap",
                    "value": {
                      "request_id": "e39cb057-92fc-4b59-b84e-02fec29a0f24",
                      "status": "Approved",
                      "message": "The verification code is correct.",
                      "email": {
                        "status": "Approved",
                        "email": "alice@example.com",
                        "is_breached": false,
                        "breaches": [],
                        "is_disposable": false,
                        "is_undeliverable": false,
                        "verification_attempts": 1,
                        "verified_at": "2026-06-12T01:24:47.311323Z",
                        "warnings": [],
                        "lifecycle": [
                          {
                            "type": "EMAIL_VERIFICATION_MESSAGE_SENT",
                            "timestamp": "2026-06-12T01:23:39.580554+00:00",
                            "details": {
                              "status": "Success",
                              "reason": null
                            },
                            "fee": 0.02
                          },
                          {
                            "type": "VALID_CODE_ENTERED",
                            "timestamp": "2026-06-12T01:24:47.311201+00:00",
                            "details": {
                              "code_tried": "123456",
                              "status": "Approved"
                            },
                            "fee": 0
                          },
                          {
                            "type": "EMAIL_VERIFICATION_APPROVED",
                            "timestamp": "2026-06-12T01:24:47.384292+00:00",
                            "details": null,
                            "fee": 0
                          }
                        ],
                        "matches": []
                      },
                      "vendor_data": "user-1234",
                      "metadata": null,
                      "created_at": "2026-06-12T01:24:47.401719+00:00"
                    }
                  },
                  "Approved with breach exposure": {
                    "summary": "Kode benar; paparan pelanggaran dicatat sebagai peringatan (breached_email_action=NO_ACTION)",
                    "value": {
                      "request_id": "3a1f2b6c-9d4e-4f7a-8b2c-1e5d6f7a8b9c",
                      "status": "Approved",
                      "message": "The verification code is correct.",
                      "email": {
                        "status": "Approved",
                        "email": "bob@example.com",
                        "is_breached": true,
                        "breaches": [
                          {
                            "name": "ExampleApp",
                            "domain": "exampleapp.com",
                            "breach_date": "2019-03-21",
                            "breach_emails_count": 763117,
                            "description": "In March 2019, the social platform ExampleApp suffered a data breach that exposed email addresses and passwords.",
                            "logo_path": "https://<media-host>/logos/ExampleApp.png",
                            "data_classes": [
                              "email_addresses",
                              "passwords"
                            ],
                            "is_verified": true
                          }
                        ],
                        "is_disposable": false,
                        "is_undeliverable": false,
                        "verification_attempts": 1,
                        "verified_at": "2026-06-12T01:24:47.311323Z",
                        "warnings": [
                          {
                            "feature": "EMAIL",
                            "risk": "BREACHED_EMAIL_DETECTED",
                            "additional_data": null,
                            "log_type": "information",
                            "short_description": "Breached email detected",
                            "long_description": "This email address was found in one or more known data breaches."
                          }
                        ],
                        "lifecycle": [
                          {
                            "type": "EMAIL_VERIFICATION_MESSAGE_SENT",
                            "timestamp": "2026-06-12T01:23:39.580554+00:00",
                            "details": {
                              "status": "Success",
                              "reason": null
                            },
                            "fee": 0.02
                          },
                          {
                            "type": "VALID_CODE_ENTERED",
                            "timestamp": "2026-06-12T01:24:47.311201+00:00",
                            "details": {
                              "code_tried": "835126",
                              "status": "Approved"
                            },
                            "fee": 0
                          },
                          {
                            "type": "EMAIL_VERIFICATION_APPROVED",
                            "timestamp": "2026-06-12T01:24:47.384292+00:00",
                            "details": null,
                            "fee": 0
                          }
                        ],
                        "matches": []
                      },
                      "vendor_data": "user-5678",
                      "metadata": null,
                      "created_at": "2026-06-12T01:24:47.401719+00:00"
                    }
                  },
                  "Failed (attempts remaining)": {
                    "summary": "Kode salah — pengguna dapat mencoba lagi; request_id di sini adalah UUID satu kali pakai",
                    "value": {
                      "request_id": "11111111-2222-3333-4444-555555555555",
                      "status": "Failed",
                      "message": "The verification code is incorrect. Attempts remaining: 2",
                      "email": null,
                      "vendor_data": "user-1234",
                      "metadata": null,
                      "created_at": "2026-06-12T01:24:21.512340+00:00"
                    }
                  },
                  "Declined (risk policy)": {
                    "summary": "Kode benar, tetapi alamat tersebut adalah alamat sekali pakai dan disposable_email_action=DECLINE",
                    "value": {
                      "request_id": "8c2d3e4f-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
                      "status": "Declined",
                      "message": "The verification code is correct.",
                      "email": {
                        "status": "Declined",
                        "email": "tempuser42@mailinator.com",
                        "is_breached": false,
                        "breaches": [],
                        "is_disposable": true,
                        "is_undeliverable": false,
                        "verification_attempts": 1,
                        "verified_at": "2026-06-12T01:24:47.311323Z",
                        "warnings": [
                          {
                            "feature": "EMAIL",
                            "risk": "DISPOSABLE_EMAIL_DETECTED",
                            "additional_data": null,
                            "log_type": "error",
                            "short_description": "Disposable email detected",
                            "long_description": "The system detected that the email is disposable, which is not allowed."
                          }
                        ],
                        "lifecycle": [
                          {
                            "type": "EMAIL_VERIFICATION_MESSAGE_SENT",
                            "timestamp": "2026-06-12T01:23:39.580554+00:00",
                            "details": {
                              "status": "Success",
                              "reason": null
                            },
                            "fee": 0.02
                          },
                          {
                            "type": "VALID_CODE_ENTERED",
                            "timestamp": "2026-06-12T01:24:47.311201+00:00",
                            "details": {
                              "code_tried": "123456",
                              "status": "Approved"
                            },
                            "fee": 0
                          },
                          {
                            "type": "EMAIL_VERIFICATION_DECLINED",
                            "timestamp": "2026-06-12T01:24:47.384292+00:00",
                            "details": {
                              "reason": "DISPOSABLE_EMAIL_DETECTED"
                            },
                            "fee": 0
                          }
                        ],
                        "matches": []
                      },
                      "vendor_data": "user-1234",
                      "metadata": null,
                      "created_at": "2026-06-12T01:24:47.401719+00:00"
                    }
                  },
                  "Expired or Not Found": {
                    "summary": "Tidak ada verifikasi tertunda untuk alamat ini dalam 5 menit terakhir",
                    "value": {
                      "request_id": "88808a77-06e9-4cb0-85f5-9c052ddfd987",
                      "status": "Expired or Not Found",
                      "message": "No pending email verification found in the last 5 minutes.",
                      "vendor_data": null,
                      "metadata": null,
                      "created_at": "2026-06-12T01:24:59.887904+00:00"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Kesalahan validasi — envelope kesalahan kolom DRF: satu array pesan per kolom yang bermasalah.",
            "content": {
              "application/json": {
                "examples": {
                  "Invalid email": {
                    "summary": "Alamat email salah format",
                    "value": {
                      "email": [
                        "Enter a valid email address."
                      ]
                    }
                  },
                  "Missing code": {
                    "summary": "`code` tidak disertakan dalam bodi",
                    "value": {
                      "code": [
                        "This field is required."
                      ]
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Izin ditolak. Dikembalikan ketika header `x-api-key` tidak ada; kunci yang salah, dicabut, atau kedaluwarsa mengembalikan `401`. Pemeriksaan ini gratis, sehingga tidak ada pemeriksaan kredit di sini.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing or invalid API key": {
                    "summary": "Tidak ada header `x-api-key`, atau kuncinya tidak valid/dicabut",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Batas laju terlampaui. Endpoint POST/PATCH/DELETE berbagi anggaran 300 permintaan penulisan per menit per kunci API (pembuatan transaksi dan ingesti event memiliki anggaran terpisah sebesar 600). Respons menyertakan header `X-RateLimit-Limit`, `X-RateLimit-Remaining`, `X-RateLimit-Reset`, dan `Retry-After`.",
            "content": {
              "application/json": {
                "examples": {
                  "Write rate limit exceeded": {
                    "summary": "Lebih dari 300 permintaan tulis pada menit ini",
                    "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": []
          }
        ]
      }
    },
    "/v3/workflows/": {
      "get": {
        "summary": "Daftar alur kerja",
        "description": "Daftar alur kerja Anda, terbaru terlebih dahulu, dalam amplop paginasi limit/offset (`{count, next, previous, results}`, ukuran halaman default 50). Setiap baris adalah satu versi; `workflow_id` adalah ID grup stabil dan sesi baru menggunakan versi `published` terbaru.",
        "operationId": "list_workflows",
        "x-didit-sdk": {
          "resource": "workflows",
          "method": "list",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Workflows"
        ],
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 50
            },
            "description": "Ukuran halaman (jumlah alur kerja per halaman)."
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 0
            },
            "description": "Jumlah baris yang dilewati sebelum alur kerja pertama yang dikembalikan."
          }
        ],
        "responses": {
          "200": {
            "description": "Satu halaman alur kerja yang diurutkan berdasarkan `created_at` menurun, dibungkus dalam amplop paginasi. Setiap item dalam `results` adalah `WorkflowListItem`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "count": {
                      "type": "integer",
                      "description": "Jumlah total versi alur kerja untuk aplikasi."
                    },
                    "next": {
                      "type": "string",
                      "format": "uri",
                      "nullable": true,
                      "description": "URL halaman berikutnya, atau `null` pada halaman terakhir."
                    },
                    "previous": {
                      "type": "string",
                      "format": "uri",
                      "nullable": true,
                      "description": "URL halaman sebelumnya, atau `null` pada halaman pertama."
                    },
                    "results": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/WorkflowListItem"
                      }
                    }
                  }
                },
                "examples": {
                  "Two workflows": {
                    "summary": "Alur kerja KYC default dan draf alur kerja KYC + AML",
                    "value": {
                      "count": 2,
                      "next": null,
                      "previous": null,
                      "results": [
                        {
                          "uuid": "a1b2c3d4-5678-90ab-cdef-111111111111",
                          "workflow_id": "a1b2c3d4-5678-90ab-cdef-111111111111",
                          "workflow_label": "Standard KYC",
                          "workflow_type": "kyc",
                          "is_default": true,
                          "is_archived": false,
                          "is_white_label_enabled": false,
                          "total_price": 0.15,
                          "min_price": 0.15,
                          "max_price": 0.15,
                          "features": "OCR + LIVENESS + FACE_MATCH",
                          "is_simple_workflow": true,
                          "is_editable": false,
                          "workflow_url": "https://verify.didit.me/u/_yljPOx8RWG3UAz5ZRQGVQ",
                          "max_retry_attempts": 3,
                          "retry_window_days": 7,
                          "session_expiration_time": 604800,
                          "version": 2,
                          "status": "published",
                          "has_draft": false,
                          "created_by": {
                            "name": "Alex Mateo",
                            "email": "alex@example.com",
                            "type": "user"
                          },
                          "updated_at": "2026-04-12T10:30:00Z"
                        },
                        {
                          "uuid": "b2c3d4e5-6789-01bc-defa-222222222222",
                          "workflow_id": "b2c3d4e5-6789-01bc-defa-222222222222",
                          "workflow_label": "Full Verification + AML",
                          "workflow_type": "kyc",
                          "is_default": false,
                          "is_archived": false,
                          "is_white_label_enabled": false,
                          "total_price": 0.25,
                          "min_price": 0.25,
                          "max_price": 0.25,
                          "features": "OCR + LIVENESS + FACE_MATCH + AML",
                          "is_simple_workflow": true,
                          "is_editable": true,
                          "workflow_url": "https://verify.didit.me/u/Aq3kPOx8RWG3UAz5ZRQGVQ",
                          "max_retry_attempts": 3,
                          "retry_window_days": 7,
                          "session_expiration_time": 604800,
                          "version": 1,
                          "status": "draft",
                          "has_draft": true,
                          "created_by": null,
                          "updated_at": "2026-04-15T18:05:21Z"
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Kunci API tidak ada, salah format, kedaluwarsa, atau milik aplikasi lain. Isi: `{\"detail\": \"You do not have permission to perform this action.\"}`. Segarkan token melalui [Auth API](/id/auth-api/get-credentials) dan coba lagi.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Invalid token": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Batas laju terlampaui. Coba lagi dengan backoff eksponensial dan patuhi header `Retry-After` jika ada."
          },
          "500": {
            "description": "Terjadi kesalahan server tak terduga saat menyusun daftar. Permintaan dapat dicoba lagi dengan aman."
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL",
            "source": "curl -X GET 'https://verification.didit.me/v3/workflows/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Accept: application/json'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nfor item in client.workflows.list():\n    print(item)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nfor await (const item of didit.workflows.list()) {\n  console.log(item);\n}"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\niter := client.Workflows.ListAutoPaging(ctx, didit.WorkflowsListParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nfor (var item : client.workflows().list()) {\n    System.out.println(item);\n}"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\nforeach ($didit->workflows->list() as $item) {\n    print_r($item->toArray());\n}"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.workflows.list.auto_paging_each do |item|\n  puts item.to_h\nend"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.Workflows.ListAsync())\n{\n    Console.WriteLine(JsonSerializer.Serialize(item));\n}"
          }
        ]
      },
      "post": {
        "summary": "Buat alur kerja",
        "description": "Buat alur kerja sederhana. Kirim `features` dalam urutan eksekusi (aturan pengurutan berlaku); default ke `published` v1. Body HANYA menerima kolom yang tercantum dalam `SimpleWorkflowRequest` — kunci lain apa pun (termasuk `workflow_type`) akan ditolak dengan 400. Tidak idempoten — setiap panggilan membuat alur kerja baru. Maksimum 50 alur kerja per aplikasi.",
        "operationId": "create_workflow",
        "x-didit-sdk": {
          "resource": "workflows",
          "method": "create",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Workflows"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SimpleWorkflowRequest"
              },
              "examples": {
                "Simple KYC": {
                  "summary": "Alur kerja linear ID, liveness, dan pencocokan wajah",
                  "value": {
                    "workflow_label": "Standard KYC",
                    "features": [
                      {
                        "feature": "OCR",
                        "config": {
                          "duplicated_user_action": "review"
                        }
                      },
                      {
                        "feature": "LIVENESS",
                        "config": {
                          "face_liveness_method": "passive"
                        }
                      },
                      {
                        "feature": "FACE_MATCH",
                        "config": {
                          "face_match_score_decline_threshold": 40,
                          "face_match_score_review_threshold": 60
                        }
                      }
                    ]
                  }
                },
                "KYC + AML": {
                  "summary": "Jalankan AML setelah verifikasi identitas",
                  "value": {
                    "workflow_label": "KYC with AML",
                    "features": [
                      {
                        "feature": "OCR"
                      },
                      {
                        "feature": "AML",
                        "config": {
                          "aml_score_review_threshold": 70,
                          "aml_score_approve_threshold": 30
                        }
                      }
                    ]
                  }
                },
                "Questionnaire workflow": {
                  "summary": "Jalankan kuesioner yang dibuat dengan POST /v3/questionnaires/",
                  "value": {
                    "workflow_label": "Source of Funds",
                    "features": [
                      {
                        "feature": "QUESTIONNAIRE",
                        "config": {
                          "questionnaire_uuid": "11111111-2222-3333-4444-555555555555",
                          "review_questionnaire_manually": true
                        }
                      }
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Alur kerja dibuat. Badan respons adalah konfigurasi LENGKAP alur kerja — serialisasi mentah `VerificationSettings` yang sama seperti yang dikembalikan oleh `GET /v3/workflows/{settings_uuid}/` (~190 kolom: setiap pengalih fitur, ambang batas, tindakan, dan `workflow_graph` yang dihasilkan), bukan item daftar ringkas. Simpan `uuid` (juga ditampilkan sebagai `workflow_id`) agar Anda dapat mereferensikannya dari panggilan pembuatan sesi berikutnya. Catatan: `features` berupa string yang digabungkan dengan `\" + \"` dan harga berupa angka JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WorkflowDetail"
                },
                "examples": {
                  "Created (abbreviated)": {
                    "summary": "Kolom utama dari objek konfigurasi lengkap",
                    "value": {
                      "uuid": "c3d4e5f6-7890-12cd-ef34-333333333333",
                      "workflow_id": "c3d4e5f6-7890-12cd-ef34-333333333333",
                      "workflow_label": "Standard KYC",
                      "workflow_type": null,
                      "is_default": false,
                      "is_archived": false,
                      "total_price": 0.15,
                      "min_price": 0.15,
                      "max_price": 0.15,
                      "features": "OCR + LIVENESS + FACE_MATCH",
                      "is_simple_workflow": false,
                      "is_editable": false,
                      "workflow_url": "https://verify.didit.me/u/w9TkPOx8RWG3UAz5ZRQGVQ",
                      "workflow_graph": {
                        "start_node": "ocr",
                        "nodes": "... one node per feature plus a final status node ..."
                      },
                      "max_retry_attempts": 3,
                      "retry_window_days": 7,
                      "session_expiration_time": 604800,
                      "version": 1,
                      "status": "published",
                      "published_at": "2026-05-17T10:30:00Z",
                      "created_at": "2026-05-17T10:30:00Z",
                      "updated_at": "2026-05-17T10:30:00Z"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Kesalahan validasi. Penyebab umum: kunci tingkat atas di luar daftar putih yang diterima (misalnya `workflow_type`), nilai `feature` yang tidak dikenal, fitur yang ditempatkan sebelum dependensinya (misalnya `FACE_MATCH` sebelum `OCR`), fitur pasif (`AML`, `IP_ANALYSIS`, `DATABASE_VALIDATION`, `KYB_KEY_PEOPLE`) yang digunakan sebagai langkah pertama, fitur `QUESTIONNAIRE` yang `config.questionnaire_uuid`-nya tidak ada untuk aplikasi ini, fitur `SIGNATURE` yang akan aktif tanpa dokumen untuk ditandatangani, fitur `SIGNATURE` pada `signature_level: \"aes\"` saat Advanced (AES) tidak tersedia (`aes_not_available`, lihat `signature_availability` pada alur kerja), atau ambang batas di luar rentang. Isi respons berupa objek kesalahan validasi DRF — kuncinya adalah nama kolom, nilainya adalah larik pesan yang dapat dibaca manusia.",
            "content": {
              "application/json": {
                "examples": {
                  "Advanced (AES) not available": {
                    "value": {
                      "features": {
                        "signature_level": [
                          "Node 'signature': Advanced (AES) is not available yet (aes_not_available)."
                        ]
                      }
                    }
                  },
                  "Signature step with no document": {
                    "value": {
                      "features": {
                        "non_field_errors": [
                          "Node 'signature': Add a document to sign, or let each session bring its own."
                        ]
                      }
                    }
                  },
                  "Missing feature": {
                    "value": {
                      "features": [
                        "At least one feature is required."
                      ]
                    }
                  },
                  "Unknown top-level field": {
                    "value": {
                      "workflow_type": [
                        "The v3 workflow API only accepts `workflow_label`, `is_default`, `status`, `features`, `is_white_label_enabled`, `is_desktop_allowed`, `max_retry_attempts`, `retry_window_days`, `session_expiration_time`, `face_liveness_max_attempts`, `face_match_max_attempts`."
                      ]
                    }
                  },
                  "Unknown feature": {
                    "value": {
                      "features": [
                        "Invalid feature 'FOO'. Allowed values: AGE_ESTIMATION, AML, DATABASE_VALIDATION, EMAIL_VERIFICATION, FACE_MATCH, IP_ANALYSIS, KYB_DOCUMENTS, KYB_KEY_PEOPLE, KYB_REGISTRY, LIVENESS, NFC, OCR, PHONE_VERIFICATION, PROOF_OF_ADDRESS, QUESTIONNAIRE."
                      ]
                    }
                  },
                  "Ordering": {
                    "value": {
                      "features": [
                        "Feature 'FACE_MATCH' must appear after one of: OCR."
                      ]
                    }
                  },
                  "Questionnaire not found": {
                    "value": {
                      "features": "Questionnaire '11111111-2222-3333-4444-555555555555' was not found for this application. Create the questionnaire first, then use its questionnaire_id."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Kunci API tidak ada, salah format, kedaluwarsa, atau dicakupkan ke aplikasi lain. Segarkan melalui [Auth API](/id/auth-api/get-credentials) dan coba lagi.",
            "content": {
              "application/json": {
                "examples": {
                  "Invalid token": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "415": {
            "description": "Tipe media tidak didukung. Atur `Content-Type: application/json` dan kirim body JSON."
          },
          "429": {
            "description": "Batas laju terlampaui. Coba lagi dengan backoff eksponensial."
          },
          "500": {
            "description": "Terjadi kesalahan server tak terduga saat membuat alur kerja. Aman untuk dicoba lagi."
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL",
            "source": "curl -X POST 'https://verification.didit.me/v3/workflows/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"workflow_label\": \"Standard KYC\",\n    \"features\": [\n      {\"feature\": \"OCR\"},\n      {\"feature\": \"LIVENESS\", \"config\": {\"face_liveness_method\": \"passive\"}},\n      {\"feature\": \"FACE_MATCH\", \"config\": {\"face_match_score_decline_threshold\": 40, \"face_match_score_review_threshold\": 60}}\n    ]\n  }'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.workflows.create(\n    workflow_label=\"Standard KYC\",\n    features=[{\n        \"feature\": \"OCR\",\n        \"config\": {\"duplicated_user_action\": \"review\"},\n    }, {\n        \"feature\": \"LIVENESS\",\n        \"config\": {\"face_liveness_method\": \"passive\"},\n    }, {\n        \"feature\": \"FACE_MATCH\",\n        \"config\": {\"face_match_score_decline_threshold\": 40, \"face_match_score_review_threshold\": 60},\n    }],\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.workflows.create({\n  workflow_label: \"Standard KYC\",\n  features: [{\n    feature: \"OCR\",\n    config: { duplicated_user_action: \"review\" },\n  }, {\n    feature: \"LIVENESS\",\n    config: { face_liveness_method: \"passive\" },\n  }, {\n    feature: \"FACE_MATCH\",\n    config: { face_match_score_decline_threshold: 40, face_match_score_review_threshold: 60 },\n  }],\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Workflows.Create(ctx, didit.SimpleWorkflowRequest{\n\tWorkflowLabel: didit.String(\"Standard KYC\"),\n\tFeatures: []didit.SimpleWorkflowFeature{{\n\t\tFeature: \"OCR\",\n\t\tConfig:  didit.Some(map[string]any{\"duplicated_user_action\": \"review\"}),\n\t}, {\n\t\tFeature: \"LIVENESS\",\n\t\tConfig:  didit.Some(map[string]any{\"face_liveness_method\": \"passive\"}),\n\t}, {\n\t\tFeature: \"FACE_MATCH\",\n\t\tConfig:  didit.Some(map[string]any{\"face_match_score_decline_threshold\": 40, \"face_match_score_review_threshold\": 60}),\n\t}},\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.List;\nimport java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.SimpleWorkflowFeature;\nimport me.didit.types.SimpleWorkflowRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.workflows().create(SimpleWorkflowRequest.builder()\n        .workflowLabel(\"Standard KYC\")\n        .features(List.of(\n                SimpleWorkflowFeature.builder()\n                        .feature(SimpleWorkflowFeature.Feature.of(\"OCR\"))\n                        .config(Map.of(\"duplicated_user_action\", \"review\"))\n                        .build(),\n                SimpleWorkflowFeature.builder()\n                        .feature(SimpleWorkflowFeature.Feature.of(\"LIVENESS\"))\n                        .config(Map.of(\"face_liveness_method\", \"passive\"))\n                        .build(),\n                SimpleWorkflowFeature.builder()\n                        .feature(SimpleWorkflowFeature.Feature.of(\"FACE_MATCH\"))\n                        .config(Map.of(\"face_match_score_decline_threshold\", 40, \"face_match_score_review_threshold\", 60))\n                        .build()))\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->workflows->create([\n    'workflow_label' => 'Standard KYC',\n    'features' => [[\n        'feature' => 'OCR',\n        'config' => ['duplicated_user_action' => 'review'],\n    ], [\n        'feature' => 'LIVENESS',\n        'config' => ['face_liveness_method' => 'passive'],\n    ], [\n        'feature' => 'FACE_MATCH',\n        'config' => ['face_match_score_decline_threshold' => 40, 'face_match_score_review_threshold' => 60],\n    ]],\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.workflows.create(\n  workflow_label: \"Standard KYC\",\n  features: [{\n    feature: \"OCR\",\n    config: { duplicated_user_action: \"review\" },\n  }, {\n    feature: \"LIVENESS\",\n    config: { face_liveness_method: \"passive\" },\n  }, {\n    feature: \"FACE_MATCH\",\n    config: { face_match_score_decline_threshold: 40, face_match_score_review_threshold: 60 },\n  }]\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Workflows.CreateAsync(new SimpleWorkflowRequest\n{\n    WorkflowLabel = \"Standard KYC\",\n    Features = new SimpleWorkflowFeature[]\n    {\n        new()\n        {\n            Feature = \"OCR\",\n            Config = new Dictionary<string, object> { [\"duplicated_user_action\"] = \"review\" },\n        },\n        new()\n        {\n            Feature = \"LIVENESS\",\n            Config = new Dictionary<string, object> { [\"face_liveness_method\"] = \"passive\" },\n        },\n        new()\n        {\n            Feature = \"FACE_MATCH\",\n            Config = new Dictionary<string, object> { [\"face_match_score_decline_threshold\"] = 40, [\"face_match_score_review_threshold\"] = 60 },\n        },\n    },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/workflows/{settings_uuid}/": {
      "get": {
        "summary": "Dapatkan alur kerja",
        "description": "Ambil konfigurasi lengkap untuk satu versi alur kerja berdasarkan `settings_uuid`: toggle fitur, ambang batas, dokumen yang diizinkan, graf, kebijakan coba lagi, callback, dan harga.",
        "operationId": "get_workflow",
        "x-didit-sdk": {
          "resource": "workflows",
          "method": "retrieve",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Workflows"
        ],
        "parameters": [
          {
            "name": "settings_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID per versi dari alur kerja (nilai `uuid` yang dikembalikan oleh endpoint daftar). Setiap versi alur kerja memiliki `settings_uuid` tersendiri."
          }
        ],
        "responses": {
          "200": {
            "description": "Konfigurasi alur kerja lengkap. Bentuknya adalah serialisasi mentah `VerificationSettings` (~190 kolom: setiap sakelar fitur, ambang batas, tindakan peringatan, konfigurasi dokumen yang diizinkan, `workflow_graph`, kebijakan coba lagi, callback, dan harga). Contoh di bawah ini disingkat. Catatan: `features` adalah string yang digabungkan dengan `\" + \"` (mis. `\"OCR + LIVENESS\"`), harga berupa angka JSON, dan `is_editable` bernilai `true` hanya untuk versi `draft`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WorkflowDetail"
                },
                "examples": {
                  "KYC workflow with face match (abbreviated)": {
                    "value": {
                      "uuid": "a1b2c3d4-5678-90ab-cdef-111111111111",
                      "workflow_id": "a1b2c3d4-5678-90ab-cdef-111111111111",
                      "workflow_label": "Standard KYC",
                      "workflow_type": "kyc",
                      "is_default": true,
                      "is_archived": false,
                      "is_liveness_enabled": true,
                      "face_liveness_method": "passive",
                      "face_liveness_score_decline_threshold": 50,
                      "face_liveness_score_review_threshold": 70,
                      "is_face_match_enabled": true,
                      "face_match_score_decline_threshold": 40,
                      "face_match_score_review_threshold": 60,
                      "is_aml_enabled": false,
                      "is_phone_verification_enabled": false,
                      "is_email_verification_enabled": false,
                      "is_database_validation_enabled": false,
                      "is_ip_analysis_enabled": false,
                      "is_nfc_enabled": false,
                      "duplicated_user_action": "no_action",
                      "documents_allowed": {
                        "ESP": {
                          "P": {
                            "sides": 1,
                            "enabled": 1,
                            "subtypes": [
                              "EPASSPORT",
                              "PASSPORT_GENERIC"
                            ],
                            "preferred_characters": "latin",
                            "expiration_check_mode": "strict"
                          }
                        }
                      },
                      "max_retry_attempts": 3,
                      "retry_window_days": 7,
                      "session_expiration_time": 604800,
                      "version": 2,
                      "status": "published",
                      "published_at": "2026-04-12T10:30:00Z",
                      "is_simple_workflow": false,
                      "is_editable": false,
                      "workflow_url": "https://verify.didit.me/u/_yljPOx8RWG3UAz5ZRQGVQ",
                      "total_price": 0.15,
                      "min_price": 0.15,
                      "max_price": 0.15,
                      "features": "OCR + LIVENESS + FACE_MATCH",
                      "created_at": "2025-01-15T10:30:00Z",
                      "updated_at": "2026-04-12T10:30:00Z"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Kunci API tidak ada, memiliki format yang salah, kedaluwarsa, atau memiliki cakupan untuk aplikasi yang berbeda.",
            "content": {
              "application/json": {
                "examples": {
                  "Invalid token": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Tidak ada alur kerja dengan `settings_uuid` ini untuk aplikasi yang diautentikasi. UUID mungkin salah atau milik aplikasi lain — Didit sengaja tidak membedakan kedua kasus tersebut untuk menghindari kebocoran informasi tentang keberadaan data lintas aplikasi.",
            "content": {
              "application/json": {
                "examples": {
                  "Not found": {
                    "value": {
                      "detail": "Not found."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Batas laju terlampaui. Coba lagi dengan backoff eksponensial."
          },
          "500": {
            "description": "Terjadi kesalahan server tak terduga. Aman untuk dicoba lagi."
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL",
            "source": "curl -X GET 'https://verification.didit.me/v3/workflows/a1b2c3d4-5678-90ab-cdef-111111111111/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.workflows.retrieve(\n    \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.workflows.retrieve(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Workflows.Retrieve(ctx, \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.workflows().retrieve(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->workflows->retrieve('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.workflows.retrieve(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Workflows.RetrieveAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      },
      "patch": {
        "summary": "Perbarui alur kerja",
        "description": "Perbarui alur kerja. Pembuatan versi bergantung pada kolom `status` yang Anda kirim dan status versi saat ini: (1) tanpa `status` pada versi **diterbitkan** → versi diterbitkan diperbarui di tempat (`uuid` sama, `version` sama); (2) tanpa `status` pada **draf** → draf diperbarui dan langsung diterbitkan; (3) `status: \"published\"` pada versi **diterbitkan** → versi diterbitkan BARU dibuat di bawah `workflow_id` yang sama (`uuid` baru, `version` + 1) dan dikembalikan, serta draf yang ada dalam grup akan dihapus; (4) `status: \"draft\"` mempertahankan draf sebagai draf (simpan otomatis) tetapi ditolak dengan 400 pada versi yang telah diterbitkan (`\"Cannot revert a published version to draft.\"`). Bagian body menerima whitelist kolom ketat yang sama seperti saat pembuatan — kunci yang tidak dikenal akan ditolak dengan 400.",
        "operationId": "update_workflow",
        "x-didit-sdk": {
          "resource": "workflows",
          "method": "update",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Workflows"
        ],
        "parameters": [
          {
            "name": "settings_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID per versi dari alur kerja yang akan diperbarui."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SimpleWorkflowUpdateRequest"
              },
              "examples": {
                "Replace features": {
                  "summary": "Kirim urutan fitur lengkap yang diinginkan",
                  "value": {
                    "features": [
                      {
                        "feature": "OCR"
                      },
                      {
                        "feature": "AML"
                      }
                    ]
                  }
                },
                "Rename": {
                  "summary": "Ubah nama alur kerja",
                  "value": {
                    "workflow_label": "Premium KYC"
                  }
                },
                "Set as default": {
                  "summary": "Jadikan alur kerja ini sebagai default aplikasi",
                  "value": {
                    "is_default": true
                  }
                },
                "Update config": {
                  "summary": "Ubah konfigurasi fitur",
                  "value": {
                    "features": [
                      {
                        "feature": "OCR"
                      },
                      {
                        "feature": "LIVENESS",
                        "config": {
                          "face_liveness_method": "passive"
                        }
                      }
                    ]
                  }
                },
                "Publish a draft": {
                  "summary": "Promosikan draf ke status dipublikasikan",
                  "value": {
                    "status": "published"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Alur kerja diperbarui. Isi adalah konfigurasi PENUH dari versi yang dihasilkan (bentuk mentah `VerificationSettings` yang sama seperti `GET /v3/workflows/{settings_uuid}/`). Ketika pembaruan membuat versi baru (`status: \"published\"` dikirim pada baris yang dipublikasikan), `uuid` dan `version` yang dikembalikan berbeda dari yang Anda ubah — gunakan `uuid` yang dikembalikan untuk panggilan berikutnya.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WorkflowDetail"
                }
              }
            }
          },
          "400": {
            "description": "Kesalahan validasi — kunci tingkat teratas di luar daftar izin yang diterima, fitur yang tidak dikenal, pengurutan tidak valid, ambang batas di luar rentang, mereferensikan kuesioner yang tidak ada, fitur `SIGNATURE` yang akan aktif tanpa dokumen untuk ditandatangani, fitur `SIGNATURE` baru pada `signature_level: \"aes\"` saat Tingkat Lanjut (AES) tidak tersedia (`aes_not_available`, lihat `signature_availability` pada alur kerja; langkah yang sudah menyimpan `aes` akan mempertahankannya), atau `status: \"draft\"` yang dikirim untuk versi yang sudah dipublikasikan (`\"Cannot revert a published version to draft.\"`). Body respons adalah kesalahan validasi DRF dengan kunci berdasarkan nama kolom."
          },
          "403": {
            "description": "Kunci API tidak ada atau tidak valid.",
            "content": {
              "application/json": {
                "examples": {
                  "Invalid token": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Tidak ada alur kerja dengan `settings_uuid` ini untuk aplikasi yang diautentikasi."
          },
          "415": {
            "description": "Tipe media tidak didukung. Atur `Content-Type: application/json`."
          },
          "429": {
            "description": "Batas laju terlampaui. Coba lagi dengan backoff eksponensial."
          },
          "500": {
            "description": "Terjadi kesalahan server tak terduga. Aman untuk dicoba lagi."
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL",
            "source": "curl -X PATCH 'https://verification.didit.me/v3/workflows/a1b2c3d4-5678-90ab-cdef-111111111111/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"workflow_label\": \"Premium KYC\"}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.workflows.update(\n    \"11111111-2222-3333-4444-555555555555\",\n    features=[{\n        \"feature\": \"OCR\",\n    }, {\n        \"feature\": \"AML\",\n    }],\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.workflows.update(\"11111111-2222-3333-4444-555555555555\", {\n  features: [{\n    feature: \"OCR\",\n  }, {\n    feature: \"AML\",\n  }],\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Workflows.Update(ctx, \"11111111-2222-3333-4444-555555555555\", didit.SimpleWorkflowUpdateRequest{\n\tFeatures: didit.Some([]didit.SimpleWorkflowFeature{{\n\t\tFeature: \"OCR\",\n\t}, {\n\t\tFeature: \"AML\",\n\t}}),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.List;\nimport me.didit.Didit;\nimport me.didit.types.SimpleWorkflowFeature;\nimport me.didit.types.SimpleWorkflowUpdateRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.workflows().update(\"11111111-2222-3333-4444-555555555555\", SimpleWorkflowUpdateRequest.builder()\n        .features(List.of(\n                SimpleWorkflowFeature.builder()\n                        .feature(SimpleWorkflowFeature.Feature.of(\"OCR\"))\n                        .build(),\n                SimpleWorkflowFeature.builder()\n                        .feature(SimpleWorkflowFeature.Feature.of(\"AML\"))\n                        .build()))\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->workflows->update('11111111-2222-3333-4444-555555555555', [\n    'features' => [[\n        'feature' => 'OCR',\n    ], [\n        'feature' => 'AML',\n    ]],\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.workflows.update(\n  \"11111111-2222-3333-4444-555555555555\",\n  features: [{\n    feature: \"OCR\",\n  }, {\n    feature: \"AML\",\n  }]\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Workflows.UpdateAsync(\"11111111-2222-3333-4444-555555555555\", new SimpleWorkflowUpdateRequest\n{\n    Features = new SimpleWorkflowFeature[]\n    {\n        new()\n        {\n            Feature = \"OCR\",\n        },\n        new()\n        {\n            Feature = \"AML\",\n        },\n    },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      },
      "delete": {
        "summary": "Hapus alur kerja",
        "description": "Hapus secara permanen satu versi alur kerja (tidak dapat dibatalkan). Sesi yang ada tetap mempertahankan hasil verifikasi mereka tetapi referensi alur kerja mereka dihapus; versi lain dalam grup `workflow_id` yang sama tidak dihapus.",
        "operationId": "delete_workflow",
        "x-didit-sdk": {
          "resource": "workflows",
          "method": "delete",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Workflows"
        ],
        "parameters": [
          {
            "name": "settings_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID per versi dari alur kerja yang akan dihapus."
          }
        ],
        "responses": {
          "204": {
            "description": "Alur kerja dihapus. Badan respons kosong."
          },
          "403": {
            "description": "Kunci API tidak ada atau tidak valid.",
            "content": {
              "application/json": {
                "examples": {
                  "Invalid token": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Tidak ada alur kerja dengan `settings_uuid` ini untuk aplikasi yang diautentikasi.",
            "content": {
              "application/json": {
                "examples": {
                  "Not found": {
                    "value": {
                      "detail": "Not found."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Batas laju terlampaui. Coba lagi dengan backoff eksponensial."
          },
          "500": {
            "description": "Terjadi kesalahan server tak terduga. Aman untuk dicoba lagi."
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL",
            "source": "curl -X DELETE 'https://verification.didit.me/v3/workflows/a1b2c3d4-5678-90ab-cdef-111111111111/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nclient.workflows.delete(\n    \"11111111-2222-3333-4444-555555555555\",\n)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nawait didit.workflows.delete(\"11111111-2222-3333-4444-555555555555\");"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nif err := client.Workflows.Delete(ctx, \"11111111-2222-3333-4444-555555555555\"); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nclient.workflows().delete(\"11111111-2222-3333-4444-555555555555\");"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$didit->workflows->delete('11111111-2222-3333-4444-555555555555');"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.workflows.delete(\"11111111-2222-3333-4444-555555555555\")"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nawait client.Workflows.DeleteAsync(\"11111111-2222-3333-4444-555555555555\");"
          }
        ]
      }
    },
    "/v3/questionnaires/": {
      "get": {
        "summary": "Mencantumkan kuesioner",
        "description": "Daftar kuesioner Anda, terbaru terlebih dahulu, dalam amplop paginasi limit/offset (`{count, next, previous, results}`, ukuran halaman default 50). Setiap baris adalah satu versi; `questionnaire_group_id` adalah ID grup stabil yang merujuk ke versi `published` terbaru.",
        "operationId": "list_questionnaires",
        "x-didit-sdk": {
          "resource": "questionnaires",
          "method": "list",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Questionnaires"
        ],
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 50
            },
            "description": "Ukuran halaman (jumlah kuesioner per halaman)."
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 0
            },
            "description": "Jumlah baris yang dilewati sebelum kuesioner pertama yang dikembalikan."
          }
        ],
        "responses": {
          "200": {
            "description": "Satu halaman kuesioner yang diurutkan berdasarkan `created_at` menurun, dibungkus dalam amplop paginasi. Setiap item dalam `results` adalah `QuestionnaireListItem`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "count": {
                      "type": "integer",
                      "description": "Jumlah total versi kuesioner untuk aplikasi."
                    },
                    "next": {
                      "type": "string",
                      "format": "uri",
                      "nullable": true,
                      "description": "URL halaman berikutnya, atau `null` pada halaman terakhir."
                    },
                    "previous": {
                      "type": "string",
                      "format": "uri",
                      "nullable": true,
                      "description": "URL halaman sebelumnya, atau `null` pada halaman pertama."
                    },
                    "results": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/QuestionnaireListItem"
                      }
                    }
                  }
                },
                "examples": {
                  "One questionnaire": {
                    "summary": "Kuesioner dwibahasa sederhana",
                    "value": {
                      "count": 1,
                      "next": null,
                      "previous": null,
                      "results": [
                        {
                          "uuid": "11111111-2222-3333-4444-555555555555",
                          "title": "KYC Questionnaire",
                          "description": "Additional verification questions",
                          "languages": [
                            "en",
                            "es"
                          ],
                          "default_language": "en",
                          "is_active": true,
                          "is_simple_questionnaire": true,
                          "created_at": "2026-04-23T09:55:00Z",
                          "updated_at": "2026-04-23T10:00:00Z",
                          "question_types": [
                            "SHORT_TEXT",
                            "MULTIPLE_CHOICE",
                            "FILE_UPLOAD"
                          ],
                          "workflow_names": [],
                          "questionnaire_group_id": "11111111-2222-3333-4444-555555555555",
                          "version": 1,
                          "status": "published",
                          "published_at": "2026-04-23T10:00:00Z",
                          "is_editable": false
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Kunci API tidak ada, format salah, kedaluwarsa, atau memiliki cakupan untuk aplikasi yang berbeda.",
            "content": {
              "application/json": {
                "examples": {
                  "Invalid token": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Batas laju terlampaui. Coba lagi dengan backoff eksponensial."
          },
          "500": {
            "description": "Terjadi kesalahan server tak terduga saat menyusun daftar. Aman untuk dicoba lagi."
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL",
            "source": "curl -X GET 'https://verification.didit.me/v3/questionnaires/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nfor item in client.questionnaires.list():\n    print(item)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nfor await (const item of didit.questionnaires.list()) {\n  console.log(item);\n}"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\niter := client.Questionnaires.ListAutoPaging(ctx, didit.QuestionnairesListParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nfor (var item : client.questionnaires().list()) {\n    System.out.println(item);\n}"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\nforeach ($didit->questionnaires->list() as $item) {\n    print_r($item->toArray());\n}"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.questionnaires.list.auto_paging_each do |item|\n  puts item.to_h\nend"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.Questionnaires.ListAsync())\n{\n    Console.WriteLine(JsonSerializer.Serialize(item));\n}"
          }
        ]
      },
      "post": {
        "summary": "Buat kuesioner",
        "description": "Buat kuesioner linier sederhana. Kirim `form_elements` sesuai urutan tampilan; percabangan dan grup berulang memerlukan Console. Default ke `published` v1.",
        "operationId": "create_questionnaire",
        "x-didit-sdk": {
          "resource": "questionnaires",
          "method": "create",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Questionnaires"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SimpleQuestionnaireRequest"
              },
              "examples": {
                "Simple": {
                  "summary": "Kuesioner dasar",
                  "value": {
                    "title": "Customer Onboarding",
                    "description": "Additional information needed for verification",
                    "default_language": "en",
                    "languages": [
                      "en"
                    ],
                    "is_active": true,
                    "form_elements": [
                      {
                        "id": "occupation",
                        "element_type": "short_text",
                        "label": {
                          "en": "What is your occupation?"
                        },
                        "is_required": true,
                        "placeholder": {
                          "en": "Software engineer"
                        }
                      },
                      {
                        "id": "source_of_funds",
                        "element_type": "multiple_choice",
                        "label": {
                          "en": "Source of funds"
                        },
                        "is_required": true,
                        "options": [
                          {
                            "value": "employment",
                            "label": {
                              "en": "Employment"
                            }
                          },
                          {
                            "value": "business",
                            "label": {
                              "en": "Business"
                            }
                          },
                          {
                            "value": "investments",
                            "label": {
                              "en": "Investments"
                            }
                          },
                          {
                            "value": "other",
                            "label": {
                              "en": "Other"
                            }
                          }
                        ]
                      }
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Kuesioner dibuat. Respons menyertakan `questionnaire_id` — simpan untuk mereferensikan kuesioner ini dari alur kerja atau panggilan pembaruan/penghapusan mendatang.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/QuestionnaireDetail"
                },
                "examples": {
                  "Created": {
                    "value": {
                      "questionnaire_id": "11111111-2222-3333-4444-555555555555",
                      "title": "Customer Onboarding",
                      "description": "Additional information needed for verification",
                      "languages": [
                        "en"
                      ],
                      "default_language": "en",
                      "is_active": true,
                      "is_simple_questionnaire": true,
                      "graph": {
                        "start_node": "occupation",
                        "nodes": {
                          "occupation": {
                            "element_type": "SHORT_TEXT",
                            "is_required": true,
                            "title": {
                              "en": "What is your occupation?"
                            },
                            "next": "source_of_funds"
                          },
                          "source_of_funds": {
                            "element_type": "MULTIPLE_CHOICE",
                            "is_required": true,
                            "title": {
                              "en": "Source of funds"
                            },
                            "choices": [
                              {
                                "value": "employment",
                                "label": {
                                  "en": "Employment"
                                }
                              },
                              {
                                "value": "business",
                                "label": {
                                  "en": "Business"
                                }
                              }
                            ],
                            "next": null
                          }
                        }
                      },
                      "sections": [],
                      "questionnaire_group_id": "11111111-2222-3333-4444-555555555555",
                      "version": 1,
                      "status": "published",
                      "published_at": "2026-04-23T10:00:00Z",
                      "is_editable": false
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Kesalahan validasi. Penyebab umum: `element_type` yang tidak dikenal, kolom yang dapat diterjemahkan kehilangan terjemahan untuk salah satu dari `languages`, `languages` tidak memiliki `en`, `default_language` tidak ada di `languages`, opsi tanpa `label`, pertanyaan yang memiliki `branches`/`required_if`/`repeatable_config` (tidak didukung oleh endpoint ini), atau mengirimkan `graph` mentah alih-alih `form_elements`. Isi respons adalah kesalahan validasi DRF dengan kunci berupa nama kolom.",
            "content": {
              "application/json": {
                "examples": {
                  "Graph not accepted": {
                    "value": {
                      "graph": "The v3 questionnaire API only accepts simple `form_elements`, not `graph`."
                    }
                  },
                  "Missing label": {
                    "value": {
                      "form_elements": [
                        {
                          "label": [
                            "This field is required."
                          ]
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Kunci API tidak ada, format salah, kedaluwarsa, atau memiliki cakupan untuk aplikasi yang berbeda.",
            "content": {
              "application/json": {
                "examples": {
                  "Invalid token": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "415": {
            "description": "Tipe media tidak didukung. Atur `Content-Type: application/json` dan kirim body JSON."
          },
          "429": {
            "description": "Batas laju terlampaui. Coba lagi dengan backoff eksponensial."
          },
          "500": {
            "description": "Terjadi kesalahan server tak terduga saat membuat kuesioner. Aman untuk dicoba lagi."
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL",
            "source": "curl -X POST 'https://verification.didit.me/v3/questionnaires/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"title\": \"Customer Onboarding\",\n    \"default_language\": \"en\",\n    \"languages\": [\"en\"],\n    \"form_elements\": [\n      {\n        \"id\": \"occupation\",\n        \"element_type\": \"short_text\",\n        \"label\": {\"en\": \"What is your occupation?\"},\n        \"is_required\": true\n      }\n    ]\n  }'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.questionnaires.create(\n    title=\"Customer Onboarding\",\n    description=\"Additional information needed for verification\",\n    languages=[\"en\"],\n    default_language=\"en\",\n    is_active=True,\n    form_elements=[{\n        \"id\": \"occupation\",\n        \"element_type\": \"short_text\",\n        \"label\": {\"en\": \"What is your occupation?\"},\n        \"placeholder\": {\"en\": \"Software engineer\"},\n        \"is_required\": True,\n    }, {\n        \"id\": \"source_of_funds\",\n        \"element_type\": \"multiple_choice\",\n        \"label\": {\"en\": \"Source of funds\"},\n        \"is_required\": True,\n        \"options\": [{\n            \"value\": \"employment\",\n            \"label\": {\"en\": \"Employment\"},\n        }, {\n            \"value\": \"business\",\n            \"label\": {\"en\": \"Business\"},\n        }, {\n            \"value\": \"investments\",\n            \"label\": {\"en\": \"Investments\"},\n        }, {\n            \"value\": \"other\",\n            \"label\": {\"en\": \"Other\"},\n        }],\n    }],\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.questionnaires.create({\n  title: \"Customer Onboarding\",\n  description: \"Additional information needed for verification\",\n  languages: [\"en\"],\n  default_language: \"en\",\n  is_active: true,\n  form_elements: [{\n    id: \"occupation\",\n    element_type: \"short_text\",\n    label: { en: \"What is your occupation?\" },\n    placeholder: { en: \"Software engineer\" },\n    is_required: true,\n  }, {\n    id: \"source_of_funds\",\n    element_type: \"multiple_choice\",\n    label: { en: \"Source of funds\" },\n    is_required: true,\n    options: [{\n      value: \"employment\",\n      label: { en: \"Employment\" },\n    }, {\n      value: \"business\",\n      label: { en: \"Business\" },\n    }, {\n      value: \"investments\",\n      label: { en: \"Investments\" },\n    }, {\n      value: \"other\",\n      label: { en: \"Other\" },\n    }],\n  }],\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Questionnaires.Create(ctx, didit.SimpleQuestionnaireRequest{\n\tTitle:           \"Customer Onboarding\",\n\tDescription:     didit.String(\"Additional information needed for verification\"),\n\tLanguages:       []string{\"en\"},\n\tDefaultLanguage: didit.String(\"en\"),\n\tIsActive:        didit.Bool(true),\n\tFormElements: []didit.SimpleQuestionnaireElement{{\n\t\tID:          didit.String(\"occupation\"),\n\t\tElementType: \"short_text\",\n\t\tLabel:       map[string]string{\"en\": \"What is your occupation?\"},\n\t\tPlaceholder: didit.Some(map[string]string{\"en\": \"Software engineer\"}),\n\t\tIsRequired:  didit.Bool(true),\n\t}, {\n\t\tID:          didit.String(\"source_of_funds\"),\n\t\tElementType: \"multiple_choice\",\n\t\tLabel:       map[string]string{\"en\": \"Source of funds\"},\n\t\tIsRequired:  didit.Bool(true),\n\t\tOptions: didit.Some([]didit.SimpleQuestionnaireElementOptions{{\n\t\t\tValue: didit.String(\"employment\"),\n\t\t\tLabel: map[string]string{\"en\": \"Employment\"},\n\t\t}, {\n\t\t\tValue: didit.String(\"business\"),\n\t\t\tLabel: map[string]string{\"en\": \"Business\"},\n\t\t}, {\n\t\t\tValue: didit.String(\"investments\"),\n\t\t\tLabel: map[string]string{\"en\": \"Investments\"},\n\t\t}, {\n\t\t\tValue: didit.String(\"other\"),\n\t\t\tLabel: map[string]string{\"en\": \"Other\"},\n\t\t}}),\n\t}},\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.List;\nimport java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.SimpleQuestionnaireElement;\nimport me.didit.types.SimpleQuestionnaireRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.questionnaires().create(SimpleQuestionnaireRequest.builder()\n        .title(\"Customer Onboarding\")\n        .description(\"Additional information needed for verification\")\n        .languages(List.of(\"en\"))\n        .defaultLanguage(\"en\")\n        .isActive(true)\n        .formElements(List.of(\n                SimpleQuestionnaireElement.builder()\n                        .id(\"occupation\")\n                        .elementType(SimpleQuestionnaireElement.ElementType.of(\"short_text\"))\n                        .label(Map.of(\"en\", \"What is your occupation?\"))\n                        .placeholder(Map.of(\"en\", \"Software engineer\"))\n                        .isRequired(true)\n                        .build(),\n                SimpleQuestionnaireElement.builder()\n                        .id(\"source_of_funds\")\n                        .elementType(SimpleQuestionnaireElement.ElementType.of(\"multiple_choice\"))\n                        .label(Map.of(\"en\", \"Source of funds\"))\n                        .isRequired(true)\n                        .options(List.of(\n                                SimpleQuestionnaireElement.Options.builder()\n                                        .value(\"employment\")\n                                        .label(Map.of(\"en\", \"Employment\"))\n                                        .build(),\n                                SimpleQuestionnaireElement.Options.builder()\n                                        .value(\"business\")\n                                        .label(Map.of(\"en\", \"Business\"))\n                                        .build(),\n                                SimpleQuestionnaireElement.Options.builder()\n                                        .value(\"investments\")\n                                        .label(Map.of(\"en\", \"Investments\"))\n                                        .build(),\n                                SimpleQuestionnaireElement.Options.builder()\n                                        .value(\"other\")\n                                        .label(Map.of(\"en\", \"Other\"))\n                                        .build()))\n                        .build()))\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->questionnaires->create([\n    'title' => 'Customer Onboarding',\n    'description' => 'Additional information needed for verification',\n    'languages' => ['en'],\n    'default_language' => 'en',\n    'is_active' => true,\n    'form_elements' => [[\n        'id' => 'occupation',\n        'element_type' => 'short_text',\n        'label' => ['en' => 'What is your occupation?'],\n        'placeholder' => ['en' => 'Software engineer'],\n        'is_required' => true,\n    ], [\n        'id' => 'source_of_funds',\n        'element_type' => 'multiple_choice',\n        'label' => ['en' => 'Source of funds'],\n        'is_required' => true,\n        'options' => [[\n            'value' => 'employment',\n            'label' => ['en' => 'Employment'],\n        ], [\n            'value' => 'business',\n            'label' => ['en' => 'Business'],\n        ], [\n            'value' => 'investments',\n            'label' => ['en' => 'Investments'],\n        ], [\n            'value' => 'other',\n            'label' => ['en' => 'Other'],\n        ]],\n    ]],\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.questionnaires.create(\n  title: \"Customer Onboarding\",\n  description: \"Additional information needed for verification\",\n  languages: [\"en\"],\n  default_language: \"en\",\n  is_active: true,\n  form_elements: [{\n    id: \"occupation\",\n    element_type: \"short_text\",\n    label: { en: \"What is your occupation?\" },\n    placeholder: { en: \"Software engineer\" },\n    is_required: true,\n  }, {\n    id: \"source_of_funds\",\n    element_type: \"multiple_choice\",\n    label: { en: \"Source of funds\" },\n    is_required: true,\n    options: [{\n      value: \"employment\",\n      label: { en: \"Employment\" },\n    }, {\n      value: \"business\",\n      label: { en: \"Business\" },\n    }, {\n      value: \"investments\",\n      label: { en: \"Investments\" },\n    }, {\n      value: \"other\",\n      label: { en: \"Other\" },\n    }],\n  }]\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Questionnaires.CreateAsync(new SimpleQuestionnaireRequest\n{\n    Title = \"Customer Onboarding\",\n    Description = \"Additional information needed for verification\",\n    Languages = new string[] { \"en\" },\n    DefaultLanguage = \"en\",\n    IsActive = true,\n    FormElements = new SimpleQuestionnaireElement[]\n    {\n        new()\n        {\n            Id = \"occupation\",\n            ElementType = \"short_text\",\n            Label = new Dictionary<string, string> { [\"en\"] = \"What is your occupation?\" },\n            Placeholder = new Dictionary<string, string> { [\"en\"] = \"Software engineer\" },\n            IsRequired = true,\n        },\n        new()\n        {\n            Id = \"source_of_funds\",\n            ElementType = \"multiple_choice\",\n            Label = new Dictionary<string, string> { [\"en\"] = \"Source of funds\" },\n            IsRequired = true,\n            Options = new SimpleQuestionnaireElementOptions[]\n            {\n                new()\n                {\n                    Value = \"employment\",\n                    Label = new Dictionary<string, string> { [\"en\"] = \"Employment\" },\n                },\n                new()\n                {\n                    Value = \"business\",\n                    Label = new Dictionary<string, string> { [\"en\"] = \"Business\" },\n                },\n                new()\n                {\n                    Value = \"investments\",\n                    Label = new Dictionary<string, string> { [\"en\"] = \"Investments\" },\n                },\n                new()\n                {\n                    Value = \"other\",\n                    Label = new Dictionary<string, string> { [\"en\"] = \"Other\" },\n                },\n            },\n        },\n    },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/questionnaires/{questionnaire_uuid}/": {
      "get": {
        "summary": "Dapatkan kuesioner",
        "description": "Ambil detail kuesioner lengkap untuk satu versi berdasarkan `questionnaire_uuid`: judul, `languages`, `graph` kanonis, `sections` turunan, dan metadata versi.",
        "operationId": "get_questionnaire",
        "x-didit-sdk": {
          "resource": "questionnaires",
          "method": "retrieve",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Questionnaires"
        ],
        "parameters": [
          {
            "name": "questionnaire_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID per versi dari kuesioner (nilai `uuid` yang dikembalikan oleh endpoint daftar, juga dikembalikan sebagai `questionnaire_id` pada endpoint detail)."
          }
        ],
        "responses": {
          "200": {
            "description": "Detail kuesioner lengkap termasuk `graph` kanonis, tampilan turunan `sections`, metadata versi, dan `is_editable`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/QuestionnaireDetail"
                },
                "examples": {
                  "Published questionnaire": {
                    "value": {
                      "questionnaire_id": "11111111-2222-3333-4444-555555555555",
                      "title": "Customer Onboarding",
                      "description": "Additional information needed for verification",
                      "languages": [
                        "en"
                      ],
                      "default_language": "en",
                      "is_active": true,
                      "is_simple_questionnaire": true,
                      "graph": {
                        "start_node": "occupation",
                        "nodes": {
                          "occupation": {
                            "element_type": "SHORT_TEXT",
                            "is_required": true,
                            "title": {
                              "en": "What is your occupation?"
                            },
                            "next": "source_of_funds"
                          },
                          "source_of_funds": {
                            "element_type": "MULTIPLE_CHOICE",
                            "is_required": true,
                            "title": {
                              "en": "Source of funds"
                            },
                            "choices": [
                              {
                                "value": "employment",
                                "label": {
                                  "en": "Employment"
                                }
                              },
                              {
                                "value": "business",
                                "label": {
                                  "en": "Business"
                                }
                              }
                            ],
                            "next": null
                          }
                        }
                      },
                      "sections": [
                        {
                          "title": {},
                          "description": {},
                          "items": [
                            {
                              "uuid": "11111111-2222-3333-4444-666666666666",
                              "value": "occupation",
                              "element_type": "SHORT_TEXT",
                              "is_required": true,
                              "title": {
                                "en": "What is your occupation?"
                              }
                            }
                          ]
                        }
                      ],
                      "questionnaire_group_id": "11111111-2222-3333-4444-555555555555",
                      "version": 1,
                      "status": "published",
                      "published_at": "2026-04-23T10:00:00Z",
                      "is_editable": false
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Kunci API tidak ada, format salah, kedaluwarsa, atau memiliki cakupan untuk aplikasi yang berbeda.",
            "content": {
              "application/json": {
                "examples": {
                  "Invalid token": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Tidak ada kuesioner dengan `questionnaire_uuid` ini untuk aplikasi yang diautentikasi. Entah UUID salah atau milik aplikasi lain — API sengaja tidak membedakan kedua kasus tersebut.",
            "content": {
              "application/json": {
                "examples": {
                  "Not found": {
                    "value": {
                      "detail": "Not found."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Batas laju terlampaui. Coba lagi dengan backoff eksponensial."
          },
          "500": {
            "description": "Terjadi kesalahan server tak terduga. Aman untuk dicoba lagi."
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL",
            "source": "curl -X GET 'https://verification.didit.me/v3/questionnaires/11111111-2222-3333-4444-555555555555/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.questionnaires.retrieve(\n    \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.questionnaires.retrieve(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Questionnaires.Retrieve(ctx, \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.questionnaires().retrieve(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->questionnaires->retrieve('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.questionnaires.retrieve(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Questionnaires.RetrieveAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      },
      "patch": {
        "summary": "Perbarui kuesioner",
        "description": "Perbarui kuesioner. Pembuatan versi bergantung pada kolom `status` yang Anda kirim dan status versi saat ini: (1) tanpa `status` pada versi **diterbitkan** → versi diterbitkan diperbarui di tempat (`questionnaire_id` sama, `version` sama); (2) tanpa `status` pada **draf** → draf diperbarui dan langsung diterbitkan; (3) `status: \"published\"` pada versi **diterbitkan** → versi diterbitkan BARU dibuat di bawah `questionnaire_group_id` yang sama (`questionnaire_id` baru, `version` + 1) dan dikembalikan, serta draf yang ada dalam grup akan dihapus; (4) `status: \"draft\"` mempertahankan draf sebagai draf (simpan otomatis) tetapi ditolak dengan 400 pada versi yang telah diterbitkan (`\"Cannot revert a published version to draft.\"`).",
        "operationId": "update_questionnaire",
        "x-didit-sdk": {
          "resource": "questionnaires",
          "method": "update",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Questionnaires"
        ],
        "parameters": [
          {
            "name": "questionnaire_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID per versi dari kuesioner yang akan diperbarui."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SimpleQuestionnaireUpdateRequest"
              },
              "examples": {
                "Rename": {
                  "summary": "Ubah nama kuesioner",
                  "value": {
                    "title": "Updated Customer Onboarding"
                  }
                },
                "Replace questions": {
                  "summary": "Ganti seluruh daftar pertanyaan linier",
                  "value": {
                    "form_elements": [
                      {
                        "id": "occupation",
                        "element_type": "short_text",
                        "label": {
                          "en": "What is your occupation?"
                        },
                        "is_required": true
                      },
                      {
                        "id": "source_of_funds",
                        "element_type": "multiple_choice",
                        "label": {
                          "en": "Source of funds"
                        },
                        "options": [
                          {
                            "value": "employment",
                            "label": {
                              "en": "Employment"
                            }
                          },
                          {
                            "value": "business",
                            "label": {
                              "en": "Business"
                            }
                          }
                        ]
                      }
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Kuesioner diperbarui. Isinya adalah status terbaru dari versi yang dihasilkan — versi yang diperbarui langsung di tempat, atau versi terpublikasi yang baru dibuat saat Anda mengirim `status: \"published\"` pada baris yang sudah dipublikasikan (dalam kasus tersebut `questionnaire_id` dan `version` berbeda dari yang Anda perbarui). `questionnaire_id` dalam respons adalah UUID per versi; gunakan `questionnaire_group_id` jika Anda memerlukan pengidentifikasi grup yang stabil.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/QuestionnaireDetail"
                }
              }
            }
          },
          "400": {
            "description": "Kesalahan validasi — `element_type` tidak dikenal, terjemahan tidak ada, kolom percabangan/bersyarat tidak didukung, `languages` tidak memiliki `en`, `default_language` tidak ada di `languages`, opsi tanpa label, mengirim `graph` mentah, atau `status: \"draft\"` pada versi yang dipublikasikan (`\"Cannot revert a published version to draft.\"`). Isi respons berupa kesalahan validasi DRF dengan kunci berupa nama kolom."
          },
          "403": {
            "description": "Kunci API tidak ada atau tidak valid.",
            "content": {
              "application/json": {
                "examples": {
                  "Invalid token": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Tidak ada kuesioner dengan `questionnaire_uuid` ini untuk aplikasi yang diautentikasi."
          },
          "415": {
            "description": "Tipe media tidak didukung. Atur `Content-Type: application/json`."
          },
          "429": {
            "description": "Batas laju terlampaui. Coba lagi dengan backoff eksponensial."
          },
          "500": {
            "description": "Terjadi kesalahan server tak terduga. Aman untuk dicoba lagi."
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL",
            "source": "curl -X PATCH 'https://verification.didit.me/v3/questionnaires/11111111-2222-3333-4444-555555555555/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"title\": \"Updated Customer Onboarding\"}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.questionnaires.update(\n    \"11111111-2222-3333-4444-555555555555\",\n    title=\"Updated Customer Onboarding\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.questionnaires.update(\"11111111-2222-3333-4444-555555555555\", {\n  title: \"Updated Customer Onboarding\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Questionnaires.Update(ctx, \"11111111-2222-3333-4444-555555555555\", didit.SimpleQuestionnaireUpdateRequest{\n\tTitle: didit.String(\"Updated Customer Onboarding\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.SimpleQuestionnaireUpdateRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.questionnaires().update(\"11111111-2222-3333-4444-555555555555\", SimpleQuestionnaireUpdateRequest.builder()\n        .title(\"Updated Customer Onboarding\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->questionnaires->update('11111111-2222-3333-4444-555555555555', [\n    'title' => 'Updated Customer Onboarding',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.questionnaires.update(\n  \"11111111-2222-3333-4444-555555555555\",\n  title: \"Updated Customer Onboarding\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Questionnaires.UpdateAsync(\"11111111-2222-3333-4444-555555555555\", new SimpleQuestionnaireUpdateRequest\n{\n    Title = \"Updated Customer Onboarding\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      },
      "delete": {
        "summary": "Hapus kuesioner",
        "description": "Hapus secara permanen satu versi kuesioner (tidak dapat dibatalkan). Respons kuesioner tersimpan yang terhubung ke versi ini akan dihapus bersamanya, dan sesi yang mereferensikannya akan kehilangan tautan tersebut; versi lain dalam grup yang sama tidak dihapus. Alur kerja yang mereferensikannya tetap berjalan tetapi langkah kuesioner tidak dapat lagi memuatnya.",
        "operationId": "delete_questionnaire",
        "x-didit-sdk": {
          "resource": "questionnaires",
          "method": "delete",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Questionnaires"
        ],
        "parameters": [
          {
            "name": "questionnaire_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID per versi dari kuesioner yang akan dihapus."
          }
        ],
        "responses": {
          "204": {
            "description": "Kuesioner dihapus. Badan respons kosong."
          },
          "403": {
            "description": "Kunci API tidak ada atau tidak valid.",
            "content": {
              "application/json": {
                "examples": {
                  "Invalid token": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Tidak ada kuesioner dengan `questionnaire_uuid` ini untuk aplikasi yang diautentikasi.",
            "content": {
              "application/json": {
                "examples": {
                  "Not found": {
                    "value": {
                      "detail": "Not found."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Batas laju terlampaui. Coba lagi dengan backoff eksponensial."
          },
          "500": {
            "description": "Terjadi kesalahan server tak terduga. Aman untuk dicoba lagi."
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL",
            "source": "curl -X DELETE 'https://verification.didit.me/v3/questionnaires/11111111-2222-3333-4444-555555555555/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nclient.questionnaires.delete(\n    \"11111111-2222-3333-4444-555555555555\",\n)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nawait didit.questionnaires.delete(\"11111111-2222-3333-4444-555555555555\");"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nif err := client.Questionnaires.Delete(ctx, \"11111111-2222-3333-4444-555555555555\"); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nclient.questionnaires().delete(\"11111111-2222-3333-4444-555555555555\");"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$didit->questionnaires->delete('11111111-2222-3333-4444-555555555555');"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.questionnaires.delete(\"11111111-2222-3333-4444-555555555555\")"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nawait client.Questionnaires.DeleteAsync(\"11111111-2222-3333-4444-555555555555\");"
          }
        ]
      }
    },
    "/v3/users/": {
      "get": {
        "summary": "Daftar pengguna",
        "description": "Daftar [pengguna](/entities/users) yang dihimpun Didit dari sesi KYC yang berbagi `vendor_data` yang sama (string bentuk bebas, BUKAN UUID), ditambah pengguna yang dibuat melalui API. Dipaginasi, diurutkan berdasarkan `last_session_at` menurun. Endpoint ini tidak mendukung parameter filter atau pencarian — ambil halaman dan filter di sisi klien.",
        "operationId": "list_users",
        "x-didit-sdk": {
          "resource": "users",
          "method": "list",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Users"
        ],
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 50,
              "minimum": 1,
              "maximum": 1000000
            },
            "description": "Ukuran halaman. Nilai default-nya 50 jika dihilangkan. Tidak ada batasan maksimum yang diterapkan, tetapi jaga ukuran halaman tetap kecil demi latensi."
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 0,
              "minimum": 0,
              "maximum": 1000000
            },
            "description": "Offset berbasis nol dari rekaman pertama yang dikembalikan. Sebaiknya ikuti URL `next` dari halaman sebelumnya daripada menghitungnya secara manual."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/users/?limit=50' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nfor item in client.users.list():\n    print(item)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nfor await (const item of didit.users.list()) {\n  console.log(item);\n}"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\niter := client.Users.ListAutoPaging(ctx, didit.UsersListParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nfor (var item : client.users().list()) {\n    System.out.println(item);\n}"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\nforeach ($didit->users->list() as $item) {\n    print_r($item->toArray());\n}"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.users.list.auto_paging_each do |item|\n  puts item.to_h\nend"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.Users.ListAsync())\n{\n    Console.WriteLine(JsonSerializer.Serialize(item));\n}"
          }
        ],
        "responses": {
          "200": {
            "description": "Daftar pengguna berpaginasi dengan status verifikasi, jumlah sesi, dan rincian fitur.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "count": {
                      "type": "integer",
                      "description": "Jumlah baris yang cocok — tepat hingga 100, dibatasi pada 100 setelahnya demi performa. Jangan gunakan ini untuk mendeteksi halaman terakhir; andalkan `next` yang bernilai `null` sebagai gantinya."
                    },
                    "next": {
                      "type": "string",
                      "nullable": true,
                      "description": "URL absolut halaman berikutnya, atau `null` di halaman terakhir."
                    },
                    "previous": {
                      "type": "string",
                      "nullable": true,
                      "description": "URL absolut halaman sebelumnya, atau `null` di halaman pertama."
                    },
                    "results": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/UserListItem"
                      }
                    }
                  }
                },
                "examples": {
                  "Example": {
                    "value": {
                      "count": 2,
                      "next": null,
                      "previous": null,
                      "results": [
                        {
                          "didit_internal_id": "f4e5e1f2-94a9-4f86-8c16-2b7d9b4db418",
                          "vendor_data": "user-abc-123",
                          "display_name": null,
                          "full_name": "John Michael Doe",
                          "date_of_birth": "1990-05-15",
                          "effective_name": "John Michael Doe",
                          "status": "ACTIVE",
                          "portrait_image_url": "https://<media-host>/...",
                          "session_count": 3,
                          "approved_count": 2,
                          "declined_count": 0,
                          "in_review_count": 1,
                          "issuing_states": [
                            "USA"
                          ],
                          "approved_emails": [
                            "john@example.com"
                          ],
                          "approved_phones": [
                            "+14155551234"
                          ],
                          "features": {
                            "ID_VERIFICATION": "Approved",
                            "LIVENESS": "Approved",
                            "FACE_MATCH": "Approved",
                            "AML": "Approved"
                          },
                          "features_list": [
                            {
                              "feature": "ID_VERIFICATION",
                              "status": "Approved"
                            },
                            {
                              "feature": "LIVENESS",
                              "status": "Approved"
                            },
                            {
                              "feature": "FACE_MATCH",
                              "status": "Approved"
                            },
                            {
                              "feature": "AML",
                              "status": "Approved"
                            }
                          ],
                          "last_session_at": "2025-06-15T10:30:00Z",
                          "last_activity_at": "2025-06-15T10:30:00Z",
                          "first_session_at": "2025-06-01T08:00:00Z",
                          "tags": [
                            {
                              "uuid": "9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d",
                              "name": "VIP",
                              "color": "#2567FF"
                            }
                          ],
                          "created_at": "2025-06-01T08:00:00Z"
                        },
                        {
                          "didit_internal_id": "6ed99d53-e8f5-4cf8-9ac1-4a506cb40f6b",
                          "vendor_data": null,
                          "display_name": "Jane S.",
                          "full_name": "Jane Elizabeth Smith",
                          "date_of_birth": "1985-11-22",
                          "effective_name": "Jane S.",
                          "status": "FLAGGED",
                          "portrait_image_url": null,
                          "session_count": 1,
                          "approved_count": 0,
                          "declined_count": 0,
                          "in_review_count": 1,
                          "issuing_states": [],
                          "approved_emails": [],
                          "approved_phones": [],
                          "features": {
                            "ID_VERIFICATION": "In Review"
                          },
                          "features_list": [
                            {
                              "feature": "ID_VERIFICATION",
                              "status": "In Review"
                            }
                          ],
                          "last_session_at": "2025-06-20T14:00:00Z",
                          "last_activity_at": "2025-06-20T14:05:00Z",
                          "first_session_at": "2025-06-20T14:00:00Z",
                          "tags": [],
                          "created_at": "2025-06-20T14:00:00Z"
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Tidak ada kredensial yang diberikan. Permintaan ke jalur `/v3/users/*` tanpa header `x-api-key` (atau token `Authorization: Bearer`) akan ditolak oleh middleware autentikasi sebelum mencapai API.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing credentials": {
                    "value": {
                      "detail": "You must be authenticated with a valid access token to access this endpoint."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Kunci tidak dapat mencantumkan pengguna untuk aplikasi ini. Kunci yang hilang mengembalikan `403`; kunci yang salah, dicabut, atau kedaluwarsa mengembalikan `401`.",
            "content": {
              "application/json": {
                "examples": {
                  "Forbidden": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Batas laju terlampaui; kurangi laju permintaan dan coba lagi setelah interval yang ditunjukkan dalam `Retry-After`.",
            "content": {
              "application/json": {
                "examples": {
                  "Rate limited": {
                    "value": {
                      "detail": "Request was throttled. Expected available in 30 seconds."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/users/{vendor_data}/": {
      "get": {
        "summary": "Dapatkan pengguna",
        "description": "Ambil satu [pengguna](/entities/users) berdasarkan `vendor_data` (kecocokan persis). Menambahkan `metadata`, `comments`, dan `updated_at` ke tampilan daftar, serta mengubah `tags` ke format tautan tag terperinci.",
        "operationId": "get_user",
        "x-didit-sdk": {
          "resource": "users",
          "method": "retrieve",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Users"
        ],
        "parameters": [
          {
            "name": "vendor_data",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Pengidentifikasi unik Anda untuk pengguna — string bentuk bebas (BUKAN UUID). Ini adalah nilai yang sama dengan yang Anda teruskan sebagai `vendor_data` saat membuat sesi yang pertama kali memperkenalkan pengguna ini, dicocokkan persis seperti yang dikirim.",
            "example": "user-abc-123"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/users/user-abc-123/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.users.retrieve(\n    \"user-abc-123\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.users.retrieve(\"user-abc-123\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Users.Retrieve(ctx, \"user-abc-123\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.users().retrieve(\"user-abc-123\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->users->retrieve('user-abc-123');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.users.retrieve(\"user-abc-123\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Users.RetrieveAsync(\"user-abc-123\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "Detail pengguna lengkap termasuk metadata, log komentar/aktivitas, dan data sesi gabungan.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserDetailItem"
                },
                "examples": {
                  "Active user": {
                    "value": {
                      "didit_internal_id": "f4e5e1f2-94a9-4f86-8c16-2b7d9b4db418",
                      "vendor_data": "user-abc-123",
                      "display_name": null,
                      "full_name": "John Michael Doe",
                      "date_of_birth": "1990-05-15",
                      "effective_name": "John Michael Doe",
                      "status": "ACTIVE",
                      "metadata": {
                        "tier": "premium",
                        "source": "website"
                      },
                      "portrait_image_url": "https://<media-host>/...",
                      "session_count": 3,
                      "approved_count": 2,
                      "declined_count": 0,
                      "in_review_count": 1,
                      "issuing_states": [
                        "USA"
                      ],
                      "approved_emails": [
                        "john@example.com"
                      ],
                      "approved_phones": [
                        "+14155551234"
                      ],
                      "features": {
                        "ID_VERIFICATION": "Approved",
                        "LIVENESS": "Approved",
                        "FACE_MATCH": "Approved",
                        "AML": "Approved"
                      },
                      "features_list": [
                        {
                          "feature": "ID_VERIFICATION",
                          "status": "Approved"
                        },
                        {
                          "feature": "LIVENESS",
                          "status": "Approved"
                        },
                        {
                          "feature": "FACE_MATCH",
                          "status": "Approved"
                        },
                        {
                          "feature": "AML",
                          "status": "Approved"
                        }
                      ],
                      "last_session_at": "2025-06-15T10:30:00Z",
                      "last_activity_at": "2025-06-15T10:30:00Z",
                      "first_session_at": "2025-06-01T08:00:00Z",
                      "tags": [
                        {
                          "uuid": "9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d",
                          "tag": {
                            "uuid": "e1f2a3b4-c5d6-4e7f-8a9b-0c1d2e3f4a5b",
                            "name": "VIP",
                            "color": "#2567FF",
                            "description": null,
                            "source": "custom",
                            "created_at": "2025-05-01T09:00:00Z",
                            "updated_at": "2025-05-01T09:00:00Z"
                          },
                          "added_by_email": "analyst@acme.com",
                          "added_by_name": "Jane Analyst",
                          "created_at": "2025-06-02T11:00:00Z"
                        }
                      ],
                      "comments": [
                        {
                          "uuid": "c1111111-2222-4333-8444-555555555555",
                          "comment_type": "STATUS_CHANGED",
                          "comment": null,
                          "actor_email": "analyst@acme.com",
                          "actor_name": "Jane Analyst",
                          "previous_status": "FLAGGED",
                          "new_status": "ACTIVE",
                          "previous_value": null,
                          "new_value": null,
                          "changed_fields": [],
                          "metadata": null,
                          "mentioned_emails": [],
                          "created_at": "2025-06-01T10:30:00Z"
                        }
                      ],
                      "created_at": "2025-06-01T08:00:00Z",
                      "updated_at": "2025-06-15T10:30:00Z"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Tidak ada kredensial yang diberikan. Permintaan ke jalur `/v3/users/*` tanpa header `x-api-key` (atau token `Authorization: Bearer`) akan ditolak oleh middleware autentikasi sebelum mencapai API.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing credentials": {
                    "value": {
                      "detail": "You must be authenticated with a valid access token to access this endpoint."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Kunci API tidak valid atau dicabut, atau kunci tidak dapat membaca pengguna aplikasi ini. Kunci yang hilang mengembalikan `403`; kunci yang salah, dicabut, atau kedaluwarsa mengembalikan `401`.",
            "content": {
              "application/json": {
                "examples": {
                  "Forbidden": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Tidak ada pengguna dengan `vendor_data` yang diberikan untuk aplikasi ini.",
            "content": {
              "application/json": {
                "examples": {
                  "Not found": {
                    "value": {
                      "detail": "Not found."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Batas laju terlampaui; kurangi laju permintaan dan coba lagi setelah interval yang ditunjukkan dalam `Retry-After`.",
            "content": {
              "application/json": {
                "examples": {
                  "Rate limited": {
                    "value": {
                      "detail": "Request was throttled. Expected available in 30 seconds."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      },
      "patch": {
        "summary": "Perbarui pengguna",
        "description": "Pembaruan parsial untuk pengguna: `display_name`, `full_name`, `date_of_birth`, `status`, `metadata`, `approved_emails`/`approved_phones`/`issuing_states`. `metadata` menggantikan sepenuhnya. Mengubah `status` di sini berfungsi seperti [Perbarui Status Pengguna](#patch-/v3/users/-vendor_data-/update-status/): ini mencatat aktivitas `STATUS_CHANGED` dengan `reason` opsional, dan `BLOCKED` menambahkan `vendor_data` ke daftar blokir sistem (mengubahnya dari `BLOCKED` akan menghapus entri tersebut). Perubahan pada `display_name`, `full_name`, `date_of_birth`, atau `metadata` dicatat sebagai aktivitas `PROFILE_UPDATED`.",
        "operationId": "update_user",
        "x-didit-sdk": {
          "resource": "users",
          "method": "update",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Users"
        ],
        "parameters": [
          {
            "name": "vendor_data",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Pengidentifikasi unik Anda untuk pengguna (string bentuk bebas, BUKAN UUID).",
            "example": "user-abc-123"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X PATCH 'https://verification.didit.me/v3/users/user-abc-123/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"display_name\": \"Jane S.\", \"status\": \"FLAGGED\"}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.users.update(\n    \"user-abc-123\",\n    display_name=\"Jane S.\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.users.update(\"user-abc-123\", {\n  display_name: \"Jane S.\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Users.Update(ctx, \"user-abc-123\", didit.UsersUpdateParams{\n\tDisplayName: didit.String(\"Jane S.\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.UsersUpdateParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.users().update(\"user-abc-123\", UsersUpdateParams.builder()\n        .displayName(\"Jane S.\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->users->update('user-abc-123', [\n    'display_name' => 'Jane S.',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.users.update(\n  \"user-abc-123\",\n  display_name: \"Jane S.\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Users.UpdateAsync(\"user-abc-123\", new UsersUpdateParams\n{\n    DisplayName = \"Jane S.\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "Pengguna diperbarui. Rekor pengguna lengkap yang diperbarui (bentuk yang sama seperti Dapatkan Pengguna) dikembalikan.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserDetailItem"
                },
                "examples": {
                  "Updated": {
                    "value": {
                      "didit_internal_id": "f4e5e1f2-94a9-4f86-8c16-2b7d9b4db418",
                      "vendor_data": "user-abc-123",
                      "display_name": "Jane S.",
                      "full_name": "Jane Elizabeth Smith",
                      "date_of_birth": "1985-11-22",
                      "effective_name": "Jane S.",
                      "status": "FLAGGED",
                      "metadata": {
                        "tier": "premium"
                      },
                      "portrait_image_url": "https://<media-host>/...",
                      "session_count": 3,
                      "approved_count": 2,
                      "declined_count": 0,
                      "in_review_count": 1,
                      "issuing_states": [
                        "USA"
                      ],
                      "approved_emails": [
                        "john@example.com"
                      ],
                      "approved_phones": [
                        "+14155551234"
                      ],
                      "features": {
                        "ID_VERIFICATION": "Approved",
                        "LIVENESS": "Approved",
                        "FACE_MATCH": "Approved",
                        "AML": "Approved"
                      },
                      "features_list": [
                        {
                          "feature": "ID_VERIFICATION",
                          "status": "Approved"
                        },
                        {
                          "feature": "LIVENESS",
                          "status": "Approved"
                        },
                        {
                          "feature": "FACE_MATCH",
                          "status": "Approved"
                        },
                        {
                          "feature": "AML",
                          "status": "Approved"
                        }
                      ],
                      "last_session_at": "2025-06-15T10:30:00Z",
                      "last_activity_at": "2025-06-15T10:30:00Z",
                      "first_session_at": "2025-06-01T08:00:00Z",
                      "tags": [
                        {
                          "uuid": "9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d",
                          "tag": {
                            "uuid": "e1f2a3b4-c5d6-4e7f-8a9b-0c1d2e3f4a5b",
                            "name": "VIP",
                            "color": "#2567FF",
                            "description": null,
                            "source": "custom",
                            "created_at": "2025-05-01T09:00:00Z",
                            "updated_at": "2025-05-01T09:00:00Z"
                          },
                          "added_by_email": "analyst@acme.com",
                          "added_by_name": "Jane Analyst",
                          "created_at": "2025-06-02T11:00:00Z"
                        }
                      ],
                      "comments": [],
                      "created_at": "2025-06-01T08:00:00Z",
                      "updated_at": "2025-06-15T10:30:00Z"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Body tidak valid — biasanya `status` yang tidak dikenal atau `date_of_birth` bukan dalam format `YYYY-MM-DD`.",
            "content": {
              "application/json": {
                "examples": {
                  "Bad status": {
                    "value": {
                      "status": [
                        "\"INVALID\" is not a valid choice."
                      ]
                    }
                  },
                  "Bad date_of_birth": {
                    "value": {
                      "date_of_birth": [
                        "Date has wrong format. Use one of these formats instead: YYYY-MM-DD."
                      ]
                    }
                  },
                  "Reason too long": {
                    "value": {
                      "reason": [
                        "Ensure this field has no more than 1000 characters."
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Tidak ada kredensial yang diberikan. Permintaan ke jalur `/v3/users/*` tanpa header `x-api-key` (atau token `Authorization: Bearer`) akan ditolak oleh middleware autentikasi sebelum mencapai API.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing credentials": {
                    "value": {
                      "detail": "You must be authenticated with a valid access token to access this endpoint."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Kunci tidak dapat memperbarui pengguna untuk aplikasi ini. Kunci yang hilang mengembalikan `403`; kunci yang salah, dicabut, atau kedaluwarsa mengembalikan `401`.",
            "content": {
              "application/json": {
                "examples": {
                  "Forbidden": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Tidak ada pengguna dengan `vendor_data` yang diberikan untuk aplikasi ini.",
            "content": {
              "application/json": {
                "examples": {
                  "Not found": {
                    "value": {
                      "detail": "Not found."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Batas laju terlampaui; kurangi laju permintaan dan coba lagi setelah interval yang ditunjukkan dalam `Retry-After`.",
            "content": {
              "application/json": {
                "examples": {
                  "Rate limited": {
                    "value": {
                      "detail": "Request was throttled. Expected available in 30 seconds."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "full_name": {
                    "type": "string",
                    "nullable": true,
                    "maxLength": 512,
                    "description": "Nama lengkap pengguna"
                  },
                  "display_name": {
                    "type": "string",
                    "nullable": true,
                    "description": "Nama tampilan kustom untuk pengguna ini"
                  },
                  "date_of_birth": {
                    "type": "string",
                    "format": "date",
                    "nullable": true,
                    "description": "Tanggal lahir dalam format YYYY-MM-DD"
                  },
                  "status": {
                    "type": "string",
                    "enum": [
                      "ACTIVE",
                      "FLAGGED",
                      "BLOCKED"
                    ],
                    "description": "Status siklus hidup pengguna. Perubahan dicatat sebagai aktivitas `STATUS_CHANGED`, dan `BLOCKED` menambahkan `vendor_data` ke daftar blokir sistem (berpindah dari `BLOCKED` akan menghapus entri tersebut)."
                  },
                  "metadata": {
                    "type": "object",
                    "nullable": true,
                    "description": "Objek JSON arbitrer yang Anda lampirkan ke pengguna. **Menggantikan sepenuhnya** metadata yang ada saat pembaruan — gabungkan di sisi klien jika Anda hanya ingin menambahkan kunci."
                  },
                  "approved_emails": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Alamat email terverifikasi untuk pengguna ini, contoh `[\"john@example.com\"]`. Menggantikan daftar yang tersimpan sepenuhnya."
                  },
                  "approved_phones": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Nomor telepon terverifikasi untuk pengguna ini. Menggantikan daftar yang tersimpan sepenuhnya."
                  },
                  "issuing_states": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Negara penerbit (ISO 3166-1 alpha-3), mis. `[\"USA\"]`. Menggantikan sepenuhnya daftar yang tersimpan."
                  },
                  "reason": {
                    "type": "string",
                    "nullable": true,
                    "maxLength": 1000,
                    "description": "Alasan mengapa status berubah. Dicatat pada entri perubahan status aktivitas pengguna (`comments[].comment`, dan **Activity** di Business Console), hanya jika status benar-benar berubah. Webhook tidak menyertakannya."
                  }
                }
              },
              "examples": {
                "Rename": {
                  "summary": "Atur nama tampilan",
                  "value": {
                    "display_name": "Jane S."
                  }
                },
                "Override status": {
                  "summary": "Tandai pengguna untuk ditinjau",
                  "value": {
                    "status": "FLAGGED"
                  }
                },
                "Add metadata": {
                  "summary": "Ganti JSON metadata",
                  "value": {
                    "metadata": {
                      "tier": "premium",
                      "risk_level": "low"
                    }
                  }
                },
                "Fix extracted DOB": {
                  "summary": "Koreksi kolom profil yang diekstrak",
                  "value": {
                    "full_name": "Jane Elizabeth Smith",
                    "date_of_birth": "1985-11-22"
                  }
                },
                "Flag with reason": {
                  "summary": "Tandai pengguna dan catat alasannya",
                  "value": {
                    "status": "FLAGGED",
                    "reason": "Address does not match the billing country"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v3/users/{vendor_data}/generate-pdf/": {
      "get": {
        "summary": "Unduh laporan PDF riwayat pengguna lengkap",
        "description": "Render dan unduh satu PDF siap kepatuhan yang berisi riwayat verifikasi lengkap dari pengguna yang diidentifikasi oleh `vendor_data`. Ini adalah dokumen yang sama yang dihasilkan Console dari **User detail → Actions → Download PDF**, sehingga ekspor kepatuhan berkala tidak lagi memerlukan seseorang yang mengeklik di Console.\n\n**Isi laporan.** Halaman sampul dengan ringkasan profil (nama, tanggal lahir, negara bagian penerbit, email dan telepon yang disetujui), status terbaru dari setiap fitur, penghitung sesi, dan indeks sesi yang disertakan — diikuti oleh laporan standar dari setiap sesi yang disertakan, dalam urutan kronologis (paling lama terlebih dahulu). Setiap laporan sesi adalah dokumen yang sama yang dikembalikan oleh `GET /v3/session/{sessionId}/generate-pdf/` untuk sesi tersebut.\n\n**Sesi yang memenuhi syarat.** Hanya sesi Verifikasi Pengguna (KYC) dalam status `Approved`, `Declined`, `In Review`, atau `Kyc Expired` yang disertakan; sesi dalam status lainnya dilewati. Jika pengguna tidak memiliki sesi dalam salah satu status tersebut, endpoint akan mengembalikan `403` — lihat di bawah.\n\n**Batas maksimal.** Laporan dibatasi hingga **20 sesi terbaru** yang dapat dilaporkan. Jika pengguna memiliki lebih banyak, 20 sesi terbaru akan disertakan dan halaman sampul menyatakan berapa banyak sesi lama yang ditinggalkan. Gunakan `GET /v3/sessions/?vendor_data=…` untuk daftar lengkap dalam format JSON.\n\n**Branding.** Jika aplikasi Anda memiliki kustomisasi White Label, sampul dan setiap laporan sesi akan dirender dengan logo dan URL kebijakan privasi Anda; jika tidak, laporan akan menggunakan branding Didit. Laporan dirender dalam bahasa Inggris — tidak ada parameter bahasa.\n\n**Tanpa caching.** Setiap panggilan merender ulang PDF dari data saat ini, sehingga laporan yang dibuat setelah peninjauan manual mencerminkan keputusan peninjau. Dua panggilan untuk pengguna yang sama dapat menghasilkan berkas yang berbeda secara byte — arsipkan berkas yang diunduh jika Anda memerlukan salinan yang tidak dapat diubah.\n\n**Latensi.** Rendering bersifat sinkron dan mengunduh setiap gambar tersimpan dari setiap sesi yang disertakan, sehingga pengguna dengan banyak sesi yang memuat banyak media dapat membutuhkan waktu puluhan detik. Gunakan batas waktu pembacaan klien yang cukup longgar (disarankan 120 dtk) dan alirkan isi respons ke disk. Pembuatan laporan akan berhenti pada alokasi waktu sisi server alih-alih terus berjalan sampai klien Anda menyerah: jika alokasi waktu tersebut tercapai, respons tetap berupa PDF valid yang berisi sesi-sesi terbaru, dan sampul akan menyatakan berapa banyak yang diabaikan.\n\n**Cakupan.** Pengguna diselesaikan di dalam aplikasi yang memiliki kunci API. Kunci tidak akan pernah dapat mengekspor pengguna dari aplikasi lain — pengguna tersebut tidak ada baginya dan endpoint akan mengembalikan `404`.\n\n**Garis miring penutup.** Rute kanonikal diakhiri dengan garis miring penutup (`…/generate-pdf/`). Permintaan tanpanya akan dilayani langsung dengan respons yang sama — tidak ada pengalihan `301`, sehingga klien tidak perlu mengikuti pengalihan dan `curl` tidak memerlukan `-L`. Gunakan URL bergaris miring seperti pada contoh.",
        "operationId": "get_user_generate_pdf",
        "x-didit-sdk": {
          "resource": "users",
          "method": "generate_pdf",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Users"
        ],
        "parameters": [
          {
            "name": "vendor_data",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Pengidentifikasi unik Anda untuk pengguna — string bentuk bebas (BUKAN UUID). Ini adalah nilai yang sama dengan yang Anda teruskan sebagai `vendor_data` saat membuat sesi pengguna, dicocokkan persis seperti yang dikirim. Lakukan URL encoding pada nilai tersebut; nilai yang mengandung `/` tidak dapat dituju oleh rute ini.",
            "example": "user-abc-123"
          }
        ],
        "responses": {
          "200": {
            "description": "Dokumen PDF hasil render, dikembalikan langsung sebagai biner `application/pdf` — tidak ada pembungkus JSON dan tidak ada pengalihan URL unduhan. Isi dimulai dengan magic bytes `%PDF`. Simpan ke file `.pdf` atau alirkan langsung ke pemanggil Anda.",
            "headers": {
              "Content-Disposition": {
                "description": "`attachment; filename=user_{didit_internal_id}.pdf` — file diberi nama sesuai ID Didit stabil milik pengguna (`didit_internal_id` pada `GET /v3/users/{vendor_data}/`), bukan berdasarkan `vendor_data`.",
                "schema": {
                  "type": "string",
                  "example": "attachment; filename=user_f4e5e1f2-94a9-4f86-8c16-2b7d9b4db418.pdf"
                }
              },
              "Content-Length": {
                "description": "Ukuran total PDF dalam byte; badan respons tidak dibagi menjadi beberapa chunk.",
                "schema": {
                  "type": "integer",
                  "example": 148213
                }
              }
            },
            "content": {
              "application/pdf": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "401": {
            "description": "Tidak ada kredensial yang diberikan. Permintaan ke jalur `/v3/users/*` tanpa header `x-api-key` (atau token `Authorization: Bearer`) akan ditolak oleh middleware autentikasi sebelum mencapai API.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing credentials": {
                    "value": {
                      "detail": "You must be authenticated with a valid access token to access this endpoint."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Kegagalan otorisasi atau kelayakan. Bedakan keduanya berdasarkan string `detail`:\n\n- `\"You do not have permission to perform this action.\"` — kunci API tidak valid atau dicabut, atau permintaan membawa token pengguna Console alih-alih kunci API aplikasi.\n- `\"This user has no sessions in review, declined, approved or kyc expired to report.\"` — pengguna ada di aplikasi Anda tetapi belum ada sesinya yang berada dalam status yang dapat dilaporkan (misalnya setiap sesi masih `In Progress`, atau pengguna dibuat melalui `POST /v3/users/create/` dan belum pernah diverifikasi). Tunggu webhook `status.updated` sebelum meminta laporan.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "example": "This user has no sessions in review, declined, approved or kyc expired to report."
                    }
                  }
                },
                "examples": {
                  "Invalid credentials": {
                    "summary": "Kunci API dicabut atau tidak valid, atau token pengguna Console",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "No reportable sessions": {
                    "summary": "Pengguna ada tetapi tidak memiliki sesi Disetujui / Ditolak / Dalam Peninjauan / KYC Kedaluwarsa",
                    "value": {
                      "detail": "This user has no sessions in review, declined, approved or kyc expired to report."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Tidak ada pengguna dengan `vendor_data` yang diberikan di aplikasi di balik kunci API tersebut. Pengguna dari aplikasi lain tidak terlihat oleh kunci ini dan mengembalikan `404` yang sama.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "example": "User not found."
                    }
                  }
                },
                "examples": {
                  "Unknown user": {
                    "summary": "vendor_data tidak cocok dengan pengguna aplikasi ini mana pun",
                    "value": {
                      "detail": "User not found."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Batas laju terlampaui. Pembuatan PDF memiliki batas khusus sebesar **50 permintaan per menit per kredensial** (kunci API, token Bearer, atau IP sumber saat tidak terautentikasi), yang dibagi antara endpoint ini dan `GET /v3/session/{sessionId}/generate-pdf/`, selain batas GET global 600/menit. Tunggu selama `Retry-After` detik (juga tercermin dalam header `X-RateLimit-*`), lalu coba lagi. Laporan tidak di-cache di sisi server, jadi unduh setiap laporan satu kali dan simpan filenya alih-alih mengambilnya kembali.",
            "headers": {
              "Retry-After": {
                "description": "Detik yang harus ditunggu sebelum mencoba lagi mengirimkan permintaan.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "example": 30
                }
              },
              "X-RateLimit-Limit": {
                "description": "Jumlah maksimum pembuatan PDF yang diizinkan dalam jendela saat ini (50).",
                "schema": {
                  "type": "integer",
                  "example": 50
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Permintaan yang tersisa dalam jendela saat ini.",
                "schema": {
                  "type": "integer",
                  "example": 0
                }
              },
              "X-RateLimit-Reset": {
                "description": "Timestamp Unix (detik) saat jendela saat ini direset.",
                "schema": {
                  "type": "integer",
                  "example": 1750000000
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "Penjelasan pelanggaran batas laju yang mudah dibaca manusia.",
                      "example": "Session PDF generation rate limit exceeded. You can make up to 50 requests per minute."
                    }
                  }
                },
                "examples": {
                  "Throttled": {
                    "summary": "Lebih dari 50 pembuatan PDF dalam satu menit dari kredensial yang sama",
                    "value": {
                      "detail": "Session PDF generation rate limit exceeded. You can make up to 50 requests per minute."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL",
            "source": "curl --fail \\\n  'https://verification.didit.me/v3/users/user-abc-123/generate-pdf/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  --output user-history.pdf"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\ncontent = client.users.generate_pdf(\n    \"user-abc-123\",\n)\nwith open(\"download.pdf\", \"wb\") as file:\n    file.write(content)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import { writeFile } from \"node:fs/promises\";\nimport Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst content = await didit.users.generatePdf(\"user-abc-123\");\nawait writeFile(\"download.pdf\", Buffer.from(await content.arrayBuffer()));"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresp, err := client.Users.GeneratePDF(ctx, \"user-abc-123\")\nif err != nil {\n\tlog.Fatal(err)\n}\ndefer resp.Body.Close()\nfile, err := os.Create(\"download.pdf\")\nif err != nil {\n\tlog.Fatal(err)\n}\ndefer file.Close()\nif _, err := io.Copy(file, resp.Body); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.nio.file.Path;\nimport me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nclient.users().generatePdf(\"user-abc-123\")\n        .writeTo(Path.of(\"download.pdf\"));"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$content = $didit->users->generatePdf('user-abc-123');\n$content->saveTo('download.pdf');"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ncontent = didit.users.generate_pdf(\"user-abc-123\")\nFile.binwrite(\"download.pdf\", content)"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar content = await client.Users.GeneratePdfAsync(\"user-abc-123\");\nawait content.SaveToAsync(\"download.pdf\");"
          }
        ]
      }
    },
    "/v3/users/delete/": {
      "post": {
        "summary": "Hapus pengguna secara batch",
        "description": "**Hapus pengguna secara permanen**: catatan pengguna akan dihapus secara permanen. Untuk pemblokiran sehari-hari, lebih disarankan menggunakan [Perbarui Status Pengguna](#patch-/v3/users/-vendor_data-/update-status/) dengan `BLOCKED`. Pilih pengguna dengan `vendor_data_list`, dengan `didit_internal_id_list`, atau keduanya sekaligus; atau kirimkan `delete_all: true`. Endpoint ini tidak pernah mempersempit cakupan `delete_all` dengan filter. Filter People di Console akan ditolak dengan `400` (lihat respons `400`), sehingga niat mempersempit tidak berubah menjadi penghapusan menyeluruh. Dua pengecualian: `filter_has_approved_sessions` dan `filter_has_declined_sessions` tidak ditolak dan tidak diterapkan, jadi dengan `delete_all: true` kedua filter tersebut tetap menghapus semua pengguna; jangan kirimkan filter tersebut.\n\n**Templat biometrik:** kecuali Anda menyetel `retain_face_embeddings` ke `true`, setiap templat biometrik tanpa gambar yang disimpan untuk pengguna ini setelah penghapusan sesi (lihat `/v3/biometric-templates/`) akan dibersihkan sebelum pengguna dihapus, sehingga orang tersebut tidak lagi cocok dalam deteksi duplikat dan Pencarian Wajah. Dengan `retain_face_embeddings: true` dan `face_retention_days`, Anda memilih untuk menyimpan satu templat biometrik tanpa gambar per orang selama jumlah hari tersebut, dan data lain tentang orang tersebut tidak disimpan. Jika templat tidak dapat dibersihkan karena penyimpanan biometrik tidak tersedia, panggilan akan mengembalikan `503`, tidak ada pengguna dalam permintaan yang dihapus, dan mengulangi permintaan akan menyelesaikan proses tersebut.\n\n**Laporan regulasi yang telah diajukan:** jika data yang dipilih berada dalam laporan regulasi yang sudah final, seluruh permintaan akan ditolak dengan `409` dan tidak ada yang dihapus. Isi respons menggunakan `code: in_filed_report` dan menyebutkan setiap laporan beserta `uuid`, `report_number`, `report_type`, dan `case_uuid`. Hapus laporan tersebut, lalu ulangi permintaan.",
        "operationId": "batch_delete_users",
        "x-didit-sdk": {
          "resource": "users",
          "method": "batch_delete",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Users"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "description": "Sediakan `vendor_data_list`, `didit_internal_id_list`, atau `delete_all: true`. Kedua daftar dapat dikombinasikan dan digabungkan dengan operator OR. Jika `delete_all` bernilai `true`, ini diprioritaskan dan kedua daftar diabaikan.",
                "properties": {
                  "vendor_data_list": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Pengenal Anda sendiri yang akan dihapus, dicocokkan persis seperti yang dikirimkan."
                  },
                  "didit_internal_id_list": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "description": "ID pengguna internal Didit yang akan dihapus - `didit_internal_id` yang dikembalikan oleh endpoint pembuatan dan pengambilan."
                  },
                  "delete_all": {
                    "type": "boolean",
                    "default": false,
                    "description": "Jika `true`, menghapus setiap pengguna di aplikasi."
                  },
                  "retain_face_embeddings": {
                    "type": "boolean",
                    "default": false,
                    "description": "Pilihan eksplisit Anda untuk menyimpan satu templat biometrik bebas gambar dari setiap individu yang dihapus untuk deteksi duplikat, selama `face_retention_days`. Segala hal lain tentang individu tersebut akan dihapus. Tiadakan, atau kirim `false`, untuk menghapus templat bersama dengan pengguna. Jika `true`, `face_retention_days` wajib diisi."
                  },
                  "face_retention_days": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 3650,
                    "description": "Jumlah hari templat biometrik bebas gambar disimpan saat `retain_face_embeddings` bernilai `true`. Wajib diisi bersamanya, dan ditolak tanpanya dengan kode `400` pada `face_retention_days`.",
                    "example": 365
                  }
                }
              },
              "examples": {
                "Specific users": {
                  "summary": "Hapus pengguna berdasarkan vendor_data",
                  "value": {
                    "vendor_data_list": [
                      "user-123",
                      "user-456"
                    ]
                  }
                },
                "By Didit internal ID": {
                  "summary": "Hapus pengguna berdasarkan didit_internal_id",
                  "value": {
                    "didit_internal_id_list": [
                      "3f1c0d3e-8f0a-4c2e-9a3d-9b1f5f4a2c11"
                    ]
                  }
                },
                "All users": {
                  "summary": "Hapus semua pengguna dalam aplikasi ini",
                  "value": {
                    "delete_all": true
                  }
                },
                "Keep face templates": {
                  "summary": "Hapus pengguna dan simpan templat wajah anonim selama 365 hari",
                  "value": {
                    "vendor_data_list": [
                      "user-123"
                    ],
                    "retain_face_embeddings": true,
                    "face_retention_days": 365
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://verification.didit.me/v3/users/delete/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"vendor_data_list\": [\"user-123\", \"user-456\"]}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.users.batch_delete(\n    vendor_data_list=[\"user-123\", \"user-456\"],\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.users.batchDelete({\n  vendor_data_list: [\"user-123\", \"user-456\"],\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Users.BatchDelete(ctx, didit.UsersBatchDeleteParams{\n\tVendorDataList: didit.Some([]string{\"user-123\", \"user-456\"}),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.List;\nimport me.didit.Didit;\nimport me.didit.types.UsersBatchDeleteParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.users().batchDelete(UsersBatchDeleteParams.builder()\n        .vendorDataList(List.of(\"user-123\", \"user-456\"))\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->users->batchDelete([\n    'vendor_data_list' => ['user-123', 'user-456'],\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.users.batch_delete(vendor_data_list: [\"user-123\", \"user-456\"])\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Users.BatchDeleteAsync(new UsersBatchDeleteParams\n{\n    VendorDataList = new string[] { \"user-123\", \"user-456\" },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "Pengguna dihapus. Mengembalikan jumlah pengguna yang benar-benar dihapus.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "deleted": {
                      "type": "integer",
                      "description": "Jumlah pengguna yang dihapus (tidak termasuk nilai vendor_data yang tidak cocok dengan apa pun)."
                    }
                  }
                },
                "examples": {
                  "Deleted some": {
                    "value": {
                      "deleted": 2
                    }
                  },
                  "Nothing matched": {
                    "value": {
                      "deleted": 0
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Kesalahan validasi; tidak ada yang dihapus. Kesalahan dikelompokkan berdasarkan nama kolom. Tanpa selektor (kedua daftar tidak ada dan `delete_all` bukan `true`) isinya adalah `{\"vendor_data_list\": [\"This field is required unless delete_all is true.\"]}`; daftar kosong ditolak di bawah kuncinya sendiri dengan `\"This list may not be empty.\"`. Filter khusus Console (`filter_search`, `filter_status`, `filter_country`, `filter_date_from`, `filter_date_to`, `filter_tag`, `filter_latest_verification_status`, `filter_risk`, `filter_has_sessions`, `filter_has_open_alerts`, `filter_aml_monitoring`, `filter_can_sign_in`, `filter_auth_status`, `filter_auth_method`, atau `filter_auth_mfa_enabled`) ditolak setiap kali memiliki nilai, bahkan `false`, dengan objek yang dikelompokkan berdasarkan setiap kolom tersebut. Kunci `filter_*` lain yang tidak dikenal ditolak dengan `\"Unknown filter.\"`.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing selector": {
                    "summary": "Baik list maupun delete_all tidak diberikan",
                    "value": {
                      "vendor_data_list": [
                        "This field is required unless delete_all is true."
                      ]
                    }
                  },
                  "Console-only filter": {
                    "value": {
                      "filter_has_sessions": "This filter is Console-only and is not supported by this endpoint."
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Tidak ada kredensial yang diberikan. Permintaan ke jalur `/v3/users/*` tanpa header `x-api-key` (atau token `Authorization: Bearer`) akan ditolak oleh middleware autentikasi sebelum mencapai API.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing credentials": {
                    "value": {
                      "detail": "You must be authenticated with a valid access token to access this endpoint."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Kunci API tidak valid atau dicabut, atau kunci tidak dapat menghapus pengguna untuk aplikasi ini. Kunci yang hilang mengembalikan `403`; kunci yang salah, dicabut, atau kedaluwarsa mengembalikan `401`.",
            "content": {
              "application/json": {
                "examples": {
                  "Forbidden": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Batas laju terlampaui; kurangi laju permintaan dan coba lagi setelah interval yang ditunjukkan dalam `Retry-After`.",
            "content": {
              "application/json": {
                "examples": {
                  "Rate limited": {
                    "value": {
                      "detail": "Request was throttled. Expected available in 30 seconds."
                    }
                  }
                }
              }
            }
          },
          "503": {
            "description": "Penyimpanan biometrik tidak tersedia saat mempertahankan atau menghapus total templat biometrik. Tidak ada yang dihapus; ulangi permintaan yang sama. Coba lagi bersifat idempoten dan mengarah pada satu templat tunggal.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Retryable": {
                    "value": {
                      "detail": "The biometric-template operation could not finish because an external store is unavailable. The operation is retryable."
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "Tidak ada yang dihapus. `code` menyatakan alasannya: `in_filed_report` ketika pilihan mencakup seseorang dalam laporan regulasi yang sudah final, `subject_deletion_in_progress` ketika permintaan lain masih menghapus salah satu orang yang dipilih. Ulangi permintaan setelah penghapusan tersebut selesai.",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/InFiledReportError"
                    },
                    {
                      "$ref": "#/components/schemas/SubjectDeletionInProgressError"
                    }
                  ]
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/sessions/delete/": {
      "post": {
        "summary": "Hapus sesi KYC secara massal berdasarkan session_number",
        "description": "Hapus secara massal sesi Verifikasi Pengguna (KYC) berdasarkan `session_number` numeriknya, atau setiap sesi KYC di aplikasi Anda dengan `delete_all: true`.\n\n`session_number` adalah penghitung inkremental yang mudah dipahami manusia yang ditampilkan di daftar sesi Console dan dikembalikan sebagai `session_number` oleh endpoint pembuatan sesi dan keputusan; ini **bukan** UUID `session_id`. Untuk menghapus sesi berdasarkan UUID, atau untuk menghapus sesi Verifikasi Bisnis (KYB), yang tidak pernah disentuh oleh endpoint ini, gunakan `DELETE /v3/session/{sessionId}/delete/` sebagai gantinya.\n\n**Hingga 20 sesi dihapus dalam permintaan, lebih dari itu dijalankan sebagai job.** Jumlah sesi yang cocok menentukan hal ini, baik yang dipilih melalui `session_numbers` maupun dengan `delete_all`:\n- Hingga 20 sesi yang cocok: sesi dihapus sebelum respons dikirim, yang berupa `200` dengan satu entri per sesi di `results[]`.\n- Lebih dari 20: responsnya adalah `202` dengan job penghapusan, dan sesi dihapus di latar belakang. Lakukan polling pada `GET /v3/sessions/delete/{job_id}/` hingga `status` bernilai `COMPLETED` atau `FAILED`. Job melaporkan jumlah per hasil, tidak pernah mencantumkan sesi mana saja yang dihapusnya. Job `delete_all` hanya menghapus sesi yang dibuat sebelum permintaan; sesi yang dimulai saat job berjalan tidak akan dihapus.\n\nSetiap sesi yang dihapus mendapatkan perlakuan yang persis sama seperti endpoint penghapusan sesi tunggal: sesi, setiap upaya verifikasi di dalamnya, keputusan dan data yang diekstrak, rekaman fitur terkait (verifikasi identitas, wajah, liveness, pencocokan wajah, dan seterusnya) serta seluruh file tersimpannya akan dihapus, sesi menghilang dari setiap endpoint baca, dan URL media yang diterbitkan sebelumnya tidak dapat diakses lagi. Pengiriman webhook yang masih berada dalam antrean untuk sesi yang dihapus, beserta percobaan ulangnya, akan dibatalkan; webhook yang telah terkirim tidak terpengaruh. Entri daftar blokir **tidak** dihapus, kredit yang telah terpakai **tidak** dikembalikan dananya, dan entitas Pengguna induk **tidak** dihapus (gunakan `POST /v3/users/delete/` untuk entitas tersebut); tidak ada webhook yang dipicu untuk penghapusan ini. Penghapusan bersifat permanen dan tidak dapat dibatalkan.\n\n**Semantik pemilihan:**\n- Dengan `delete_all: true`, Anda dapat mempersempit pemilihan menggunakan filter dari `GET /v3/sessions/`, masing-masing diawali dengan `filter_` (misalnya `filter_status`, `filter_workflow_id`, `filter_date_from`). Filter yang menerima beberapa nilai di List Sessions (`status`, `workflow_id`, `country`, `region`, `document_type`, `document_name`, `session_type`, `warning`, `organization_name`) menerima string yang dipisahkan koma atau array; filter lainnya hanya menerima satu nilai. Nilai kosong akan diabaikan. Filter hanya berlaku bersamaan dengan `delete_all`, dan job penghapusan menerapkan filter yang sama.\n- Kunci `filter_*` yang tidak dikenal, atau nilai filter yang tidak dapat dibaca, akan menolak seluruh permintaan dengan `400` sebelum apa pun dihapus, sehingga filter yang salah ketik tidak akan pernah memperluas penghapusan ke setiap sesi.\n- Entri dalam `session_numbers` yang tidak cocok dengan sesi KYC aktif di aplikasi Anda (nomor yang tidak dikenal, sesi yang sudah dihapus, atau sesi milik aplikasi lain) akan **dilewati tanpa pemberitahuan**: entri tersebut tidak muncul di `results` dan tidak dihitung dalam `total` milik job.\n- Kegagalan validasi (entri non-numerik, daftar kosong, tidak menyertakan `session_numbers` maupun `delete_all`, atau retensi templat yang tidak dapat dipenuhi aplikasi) akan menolak **seluruh permintaan** dengan `400` dan tidak menghapus apa pun.\n- Sesi dihapus dalam beberapa kelompok. Jika suatu kelompok tidak dapat dihapus (misalnya karena layanan penyimpanan tidak tersedia), setiap sesi dalam kelompok tersebut dilaporkan sebagai `face_retention_outcome: failed_retryable` dan tetap ada; kelompok lainnya tidak terpengaruh. Ulangi permintaan untuk sesi-sesi tersebut. Job akan mencoba lagi kelompok tersebut secara otomatis.\n- Tidak ada batasan terdokumentasi untuk panjang daftar; batas laju penulisan bersama (di bawah) merupakan batas praktisnya.\n\n**Data biometrik wajah:** kolom opsional `retain_face_embeddings`, `face_retention_days`, `face_retention_deadline`, `deletion_instruction`, dan `instruction_id` memiliki arti yang sama seperti pada `DELETE /v3/session/{sessionId}/delete/` dan berlaku untuk setiap sesi yang cocok. Setiap hasil melaporkan `face_retention_outcome` masing-masing.\n\n**Respons:** `200 OK` dengan `results[]` untuk hingga 20 sesi yang cocok, atau `202 Accepted` dengan job penghapusan jika lebih banyak. Setiap hasil mengonfirmasi penghapusan kecuali `face_retention_outcome: failed_retryable`, yang melaporkan sesi yang TIDAK dihapus dan harus dicoba lagi. Versi sebelumnya dari endpoint ini mengembalikan `204 No Content`; perbarui klien yang memeriksa `204`.\n\n**Idempotensi:** mengulangi permintaan yang sama tidak akan menghapus apa pun lagi: nomor yang tidak lagi cocok dengan suatu sesi akan dilewati.\n\n**`delete_all: true` (destruktif):** menghapus **setiap** sesi KYC yang tersisa di aplikasi; `session_numbers` diabaikan jika parameter ini diatur. Tidak ada langkah konfirmasi dan tidak dapat dibatalkan.\n\n**Autentikasi:** kunci API di header `x-api-key`. Kredensial yang hilang atau tidak valid akan mengembalikan `403` (`{\"detail\": \"You do not have permission to perform this action.\"}`); API ini tidak pernah mengembalikan `401`.\n\n**Batas laju:** kuota penulisan bersama sebesar 300 permintaan/menit per kunci API di seluruh endpoint POST/PATCH/DELETE; jika melebihi batas ini akan mengembalikan `429`.\n\nEndpoint ini hanya menerima kunci API. Token Bearer pengguna Business Console ditolak dengan `403` (berbeda dengan penghapusan sesi tunggal yang menerima keduanya).\n\n**Laporan regulasi yang diajukan:** jika data yang dipilih berada dalam laporan regulasi yang telah difinalisasi, seluruh permintaan akan ditolak dengan `409` dan tidak ada yang dihapus. Isi respons menggunakan `code: in_filed_report` dan menyebutkan setiap laporan dengan `uuid`, `report_number`, `report_type`, dan `case_uuid`. Hapus laporan tersebut, lalu ulangi permintaan.",
        "operationId": "batch_delete_sessions",
        "x-didit-sdk": {
          "resource": "sessions",
          "method": "batch_delete",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Sessions"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "session_numbers": {
                    "type": "array",
                    "description": "Nilai numerik `session_number` dari sesi KYC yang akan dihapus, sebagai string khusus digit (angka JSON juga diterima dan dikonversi). Wajib diisi kecuali `delete_all` bernilai `true`; daftar kosong mengembalikan `400`. Setiap entri non-digit menolak seluruh permintaan dengan `400` (kecuali `delete_all` bernilai `true`, di mana validasi dilewati dan entri diabaikan). Nomor yang tidak cocok dengan sesi aktif di aplikasi Anda akan dilewati tanpa peringatan.",
                    "items": {
                      "type": "string",
                      "pattern": "^[0-9]+$",
                      "example": "1001"
                    },
                    "minItems": 1,
                    "example": [
                      "1001",
                      "1002",
                      "1003"
                    ]
                  },
                  "delete_all": {
                    "type": "boolean",
                    "description": "Jika `true`, setiap sesi KYC yang tersisa di aplikasi pemanggil akan dihapus dan `session_numbers` diabaikan, kecuali Anda mempersempit pilihan dengan kunci `filter_*`. Lebih dari 20 sesi yang cocok akan dijalankan sebagai tugas penghapusan (`202`) yang hanya mencakup sesi yang dibuat sebelum permintaan. Default ke `false`. Tidak dapat dibatalkan; tidak ada langkah konfirmasi.",
                    "default": false,
                    "example": false
                  },
                  "retain_face_embeddings": {
                    "type": "boolean",
                    "nullable": true,
                    "description": "Timpa `face_retention_policy` aplikasi untuk penghapusan ini. `true` mempertahankan satu templat biometrik wajah bebas gambar yang ditautkan ke Pengguna sesi setelah sesi dihapus; `false` menghapus embedding wajah bersama sesi; abaikan atau gunakan `null` untuk mengikuti kebijakan aplikasi. Diabaikan untuk sesi KYB dan untuk sesi tanpa embedding wajah.",
                    "example": true
                  },
                  "face_retention_days": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 3650,
                    "description": "Durasi retensi terbatas, dalam hari, untuk templat yang disimpan. Wajib diisi saat templat disimpan kecuali aplikasi sudah menyetel `face_retention_days`. `expires_at` templat adalah yang paling awal di antara durasi ini, jendela retensi data umum aplikasi, dan `face_retention_deadline`.",
                    "example": 365
                  },
                  "face_retention_deadline": {
                    "type": "string",
                    "format": "date-time",
                    "description": "Kedaluwarsa mutlak opsional untuk templat yang disimpan. Harus berada di masa mendatang.",
                    "example": "2027-08-28T00:00:00Z"
                  },
                  "deletion_instruction": {
                    "type": "string",
                    "enum": [
                      "operational_session_delete",
                      "privacy_erasure"
                    ],
                    "default": "operational_session_delete",
                    "description": "Kelas instruksi yang Anda berikan. `operational_session_delete` menghapus sesi dan mempertahankan templat hanya jika kebijakan atau `retain_face_embeddings` menentukannya. `privacy_erasure` menghapus permanen setiap templat biometrik tersimpan yang terkait dengan Pengguna sesi tersebut sebelum menghapus sesi, tidak dapat ditimpa oleh kebijakan aplikasi, dan tidak dapat digabungkan dengan `retain_face_embeddings: true` (`400`).",
                    "example": "operational_session_delete"
                  },
                  "instruction_id": {
                    "type": "string",
                    "maxLength": 255,
                    "description": "Referensi permanen Anda untuk instruksi penghapusan ini (misalnya id tiket penghapusan). Dicatat pada jejak audit dan pada setiap templat yang dipertahankan. Dihasilkan oleh Didit jika ditiadakan.",
                    "example": "dsar-2026-0142"
                  },
                  "filter_status": {
                    "description": "Mempersempit `delete_all` ke sesi yang cocok dengan filter `status` dari [Daftar Sesi](/id/sessions-api/list-sessions), dengan nilai yang sama. String yang dipisahkan koma atau sebuah array. Diabaikan tanpa `delete_all`. Nilai kosong diabaikan dan tidak mempersempit pilihan.",
                    "oneOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "array",
                        "items": {
                          "type": "string"
                        }
                      }
                    ]
                  },
                  "filter_vendor_data": {
                    "description": "Mempersempit `delete_all` ke sesi yang cocok dengan filter `vendor_data` dari [Daftar Sesi](/id/sessions-api/list-sessions), dengan nilai yang sama. Satu nilai, bukan daftar: array digabungkan menjadi satu teks yang dipisahkan koma, sehingga beberapa nilai tidak dicocokkan sebagai alternatif. Diabaikan tanpa `delete_all`. Nilai kosong diabaikan dan tidak mempersempit pilihan.",
                    "type": "string"
                  },
                  "filter_search": {
                    "description": "Mempersempit `delete_all` ke sesi yang cocok dengan filter `search` dari [Daftar Sesi](/id/sessions-api/list-sessions), dengan nilai yang sama. Satu nilai, bukan daftar: array digabungkan menjadi satu teks yang dipisahkan koma, sehingga beberapa nilai tidak dicocokkan sebagai alternatif. Diabaikan tanpa `delete_all`. Nilai kosong diabaikan dan tidak mempersempit pilihan.",
                    "type": "string"
                  },
                  "filter_workflow_id": {
                    "description": "Mempersempit `delete_all` ke sesi yang cocok dengan filter `workflow_id` dari [Daftar Sesi](/id/sessions-api/list-sessions), dengan nilai yang sama. String yang dipisahkan koma atau sebuah array. Diabaikan tanpa `delete_all`. Nilai kosong diabaikan dan tidak mempersempit pilihan.",
                    "oneOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "array",
                        "items": {
                          "type": "string"
                        }
                      }
                    ]
                  },
                  "filter_date_from": {
                    "description": "Mempersempit `delete_all` ke sesi yang cocok dengan filter `date_from` dari [List Sessions](/id/sessions-api/list-sessions), dengan nilai yang sama. Satu nilai, bukan daftar: array digabungkan menjadi satu nilai yang dipisahkan koma, sehingga beberapa nilai ditolak dengan `400`. Diabaikan tanpa `delete_all`. Nilai kosong diabaikan dan tidak mempersempit pilihan.",
                    "type": "string",
                    "format": "date"
                  },
                  "filter_date_to": {
                    "description": "Mempersempit `delete_all` ke sesi yang cocok dengan filter `date_to` dari [List Sessions](/id/sessions-api/list-sessions), dengan nilai yang sama. Satu nilai, bukan daftar: array digabungkan menjadi satu nilai yang dipisahkan koma, sehingga beberapa nilai ditolak dengan `400`. Diabaikan tanpa `delete_all`. Nilai kosong diabaikan dan tidak mempersempit pilihan.",
                    "type": "string",
                    "format": "date"
                  },
                  "filter_country": {
                    "description": "Mempersempit `delete_all` ke sesi yang cocok dengan filter `country` dari [List Sessions](/id/sessions-api/list-sessions), dengan nilai yang sama. String yang dipisahkan koma atau array. Diabaikan tanpa `delete_all`. Nilai kosong diabaikan dan tidak mempersempit pilihan.",
                    "oneOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "array",
                        "items": {
                          "type": "string"
                        }
                      }
                    ]
                  },
                  "filter_document_type": {
                    "description": "Mempersempit `delete_all` ke sesi yang cocok dengan filter `document_type` dari [List Sessions](/id/sessions-api/list-sessions), dengan nilai yang sama. String yang dipisahkan koma atau array. Diabaikan tanpa `delete_all`. Nilai kosong diabaikan dan tidak mempersempit pilihan.",
                    "oneOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "array",
                        "items": {
                          "type": "string"
                        }
                      }
                    ]
                  },
                  "filter_document_name": {
                    "description": "Mempersempit `delete_all` ke sesi yang cocok dengan filter `document_name` dari [List Sessions](/id/sessions-api/list-sessions), dengan nilai yang sama. String yang dipisahkan koma atau array. Diabaikan tanpa `delete_all`. Nilai kosong diabaikan dan tidak mempersempit pilihan.",
                    "oneOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "array",
                        "items": {
                          "type": "string"
                        }
                      }
                    ]
                  },
                  "filter_region": {
                    "description": "Mempersempit `delete_all` ke sesi yang cocok dengan filter `region` dari [Daftar Sesi](/id/sessions-api/list-sessions), dengan nilai yang sama. String yang dipisahkan koma atau sebuah array. Diabaikan tanpa `delete_all`. Nilai kosong diabaikan dan tidak mempersempit pilihan.",
                    "oneOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "array",
                        "items": {
                          "type": "string"
                        }
                      }
                    ]
                  },
                  "filter_didit_internal_id": {
                    "description": "Mempersempit `delete_all` ke sesi yang cocok dengan filter `didit_internal_id` dari [List Sessions](/id/sessions-api/list-sessions), dengan nilai yang sama. Satu nilai, bukan daftar: array digabungkan menjadi satu nilai yang dipisahkan koma, sehingga beberapa nilai ditolak dengan `400`. Diabaikan tanpa `delete_all`. Nilai kosong diabaikan dan tidak mempersempit pilihan.",
                    "type": "string",
                    "format": "uuid"
                  },
                  "filter_session_type": {
                    "description": "Mempersempit `delete_all` ke sesi yang cocok dengan filter `session_type` dari [Daftar Sesi](/id/sessions-api/list-sessions), dengan nilai yang sama. String yang dipisahkan koma atau sebuah array. Diabaikan tanpa `delete_all`. Nilai kosong diabaikan dan tidak mempersempit pilihan.",
                    "oneOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "array",
                        "items": {
                          "type": "string"
                        }
                      }
                    ]
                  },
                  "filter_api_service": {
                    "description": "Mempersempit `delete_all` ke sesi yang cocok dengan filter `api_service` dari [List Sessions](/id/sessions-api/list-sessions), dengan nilai yang sama. Satu nilai, bukan daftar: array digabungkan menjadi satu nilai yang dipisahkan koma, sehingga beberapa nilai ditolak dengan `400`. Diabaikan tanpa `delete_all`. Nilai kosong diabaikan dan tidak mempersempit pilihan.",
                    "type": "string"
                  },
                  "filter_screened_full_name": {
                    "description": "Mempersempit `delete_all` ke sesi yang cocok dengan filter `screened_full_name` dari [Daftar Sesi](/id/sessions-api/list-sessions), dengan nilai yang sama. Satu nilai, bukan daftar: array digabungkan menjadi satu teks yang dipisahkan koma, sehingga beberapa nilai tidak dicocokkan sebagai alternatif. Diabaikan tanpa `delete_all`. Nilai kosong diabaikan dan tidak mempersempit pilihan.",
                    "type": "string"
                  },
                  "filter_warning": {
                    "description": "Mempersempit `delete_all` ke sesi yang cocok dengan filter `warning` dari [Daftar Sesi](/id/sessions-api/list-sessions), dengan nilai yang sama. String yang dipisahkan koma atau sebuah array. Diabaikan tanpa `delete_all`. Nilai kosong diabaikan dan tidak mempersempit pilihan.",
                    "oneOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "array",
                        "items": {
                          "type": "string"
                        }
                      }
                    ]
                  },
                  "filter_status_initialized_as_in_review": {
                    "description": "Mempersempit `delete_all` ke sesi yang cocok dengan filter `status_initialized_as_in_review` dari [Daftar Sesi](/id/sessions-api/list-sessions), dengan nilai yang sama. Diabaikan tanpa `delete_all`. Nilai kosong diabaikan dan tidak mempersempit pilihan.",
                    "type": "boolean"
                  },
                  "filter_is_kyc_to_be_reviewed": {
                    "description": "Mempersempit `delete_all` ke sesi yang cocok dengan filter `is_kyc_to_be_reviewed` dari [List Sessions](/id/sessions-api/list-sessions), dengan nilai yang sama. Diabaikan tanpa `delete_all`. Nilai kosong diabaikan dan tidak mempersempit pilihan.",
                    "type": "boolean"
                  },
                  "filter_euuid": {
                    "description": "Mempersempit `delete_all` ke sesi yang cocok dengan filter `euuid` dari [List Sessions](/id/sessions-api/list-sessions), dengan nilai yang sama. Satu nilai, bukan daftar: array digabungkan menjadi satu nilai yang dipisahkan koma, sehingga beberapa nilai ditolak dengan `400`. Diabaikan tanpa `delete_all`. Nilai kosong diabaikan dan tidak mempersempit pilihan.",
                    "type": "string",
                    "format": "uuid"
                  },
                  "filter_organization_name": {
                    "description": "Mempersempit `delete_all` ke sesi yang cocok dengan filter `organization_name` dari [Daftar Sesi](/id/sessions-api/list-sessions), dengan nilai yang sama. String yang dipisahkan koma atau sebuah array. Dengan kunci API, ini hanya dapat mencocokkan nama organisasi Anda sendiri, sehingga ini memilih semua sesi Anda atau tidak sama sekali. Diabaikan tanpa `delete_all`. Nilai kosong diabaikan dan tidak mempersempit pilihan.",
                    "oneOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "array",
                        "items": {
                          "type": "string"
                        }
                      }
                    ]
                  }
                }
              },
              "examples": {
                "Specific sessions": {
                  "summary": "Hapus sesi tertentu berdasarkan nomor",
                  "value": {
                    "session_numbers": [
                      "1001",
                      "1002",
                      "1003"
                    ]
                  }
                },
                "All sessions": {
                  "summary": "Hapus setiap sesi KYC di aplikasi",
                  "value": {
                    "delete_all": true
                  }
                },
                "Delete and retain templates": {
                  "summary": "Hapus sesi tetapi simpan templat biometrik tanpa gambar selama 365 hari",
                  "value": {
                    "session_numbers": [
                      "1001",
                      "1002"
                    ],
                    "retain_face_embeddings": true,
                    "face_retention_days": 365,
                    "instruction_id": "post-approval-cleanup-2026-08"
                  }
                },
                "Privacy erasure": {
                  "summary": "Hapus sesi dan bersihkan setiap templat yang disimpan untuk Penggunanya",
                  "value": {
                    "session_numbers": [
                      "1001"
                    ],
                    "deletion_instruction": "privacy_erasure",
                    "instruction_id": "dsar-2026-0142"
                  }
                },
                "Filtered delete_all": {
                  "summary": "Hapus setiap sesi Ditolak dari satu alur kerja yang dibuat pada September 2026",
                  "value": {
                    "delete_all": true,
                    "filter_status": [
                      "Declined"
                    ],
                    "filter_workflow_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                    "filter_date_from": "2026-09-01",
                    "filter_date_to": "2026-09-30"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Hingga 20 sesi yang cocok ditemukan dan diproses dalam permintaan. Satu hasil per sesi yang cocok; nomor yang tidak cocok dengan apa pun (tidak dikenal atau sudah dihapus) dilewati dan tidak muncul. Hasil mengonfirmasi penghapusan kecuali jika `face_retention_outcome` adalah `failed_retryable`: sesi tersebut TIDAK dihapus dan harus dicoba lagi.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "results": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "session_id": {
                            "type": "string",
                            "format": "uuid",
                            "description": "Sesi yang dihapus."
                          },
                          "session_number": {
                            "type": "integer",
                            "nullable": true,
                            "description": "Nomor sesi yang dihapus."
                          },
                          "face_retention_outcome": {
                            "type": "string",
                            "enum": [
                              "retained_with_user",
                              "deleted",
                              "none",
                              "ineligible_no_vendor_user",
                              "failed_retryable"
                            ],
                            "description": "Hal yang terjadi pada data biometrik wajah sesi. `deleted`: embedding wajah dihapus bersama sesi (default). `retained_with_user`: sesi dihapus dan satu templat biometrik tanpa gambar tetap terhubung ke Pengguna; lihat `biometric_template_uuid`. `none`: sesi tidak memiliki embedding wajah (misalnya sesi KYC khusus dokumen tanpa swafoto dengan Deteksi Liveness; sesi KYB tidak pernah dipilih oleh endpoint ini). `ineligible_no_vendor_user`: retensi diminta tetapi sesi tidak memiliki Pengguna yang ditautkan, sehingga embedding dihapus bersama sesi. `failed_retryable` (khusus endpoint batch): grup tempat sesi ini dihapus tidak dapat dihapus (layanan penyimpanan, penyimpanan biometrik, atau penyedia pemantauan tidak tersedia); sesi ini masih ada, ulangi permintaan untuk sesi tersebut."
                          },
                          "biometric_template_uuid": {
                            "type": "string",
                            "format": "uuid",
                            "nullable": true,
                            "description": "Id templat biometrik yang disimpan saat `face_retention_outcome` adalah `retained_with_user`; jika tidak, bernilai `null`. Kelola melalui `/v3/biometric-templates/{template_uuid}/`."
                          },
                          "biometric_template_expires_at": {
                            "type": "string",
                            "format": "date-time",
                            "nullable": true,
                            "description": "Waktu templat biometrik yang disimpan dihapus, saat `face_retention_outcome` adalah `retained_with_user`; `null` jika tidak ada templat yang disimpan."
                          },
                          "deleted_child_verifications": {
                            "type": "integer",
                            "description": "Selalu `0` pada endpoint ini, yang hanya menghapus sesi KYC. Menghapus sesi Verifikasi Bisnis (KYB) dengan `DELETE /v3/session/{sessionId}/delete/` melaporkan verifikasi yang dibuatnya yang ikut terhapus bersamanya."
                          }
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "Mixed outcomes": {
                    "value": {
                      "results": [
                        {
                          "session_id": "4c5c7f3a-3b1d-4b7e-9c39-2b4f7e6a1d02",
                          "session_number": 1001,
                          "face_retention_outcome": "deleted",
                          "biometric_template_uuid": null,
                          "biometric_template_expires_at": null,
                          "deleted_child_verifications": 0
                        },
                        {
                          "session_id": "b8e1d2c3-4f5a-4b6c-8d7e-9f0a1b2c3d4e",
                          "session_number": 1002,
                          "face_retention_outcome": "retained_with_user",
                          "biometric_template_uuid": "9d2f4b6e-1c3a-4e8f-b7d5-0a1c2e3f4a5b",
                          "biometric_template_expires_at": "2027-10-09T10:15:00Z",
                          "deleted_child_verifications": 0
                        },
                        {
                          "session_id": "7a1e9c2d-5f4b-4c3a-8e2d-1b0a9f8e7d6c",
                          "session_number": 1003,
                          "face_retention_outcome": "ineligible_no_vendor_user",
                          "biometric_template_uuid": null,
                          "biometric_template_expires_at": null,
                          "deleted_child_verifications": 0
                        },
                        {
                          "session_id": "c1d2e3f4-a5b6-4c7d-8e9f-0a1b2c3d4e5f",
                          "session_number": 1004,
                          "face_retention_outcome": "failed_retryable",
                          "biometric_template_uuid": null,
                          "biometric_template_expires_at": null,
                          "deleted_child_verifications": 0
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "202": {
            "description": "Lebih dari 20 sesi cocok. Sesi-sesi tersebut dihapus di latar belakang; lakukan polling pada `GET /v3/sessions/delete/{job_id}/` hingga `status` bernilai `COMPLETED` atau `FAILED`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SessionDeletionJob"
                },
                "examples": {
                  "Job accepted": {
                    "value": {
                      "job_id": "5b8f2c1e-7d3a-4f6b-9e2c-1a0d8f7e6c5b",
                      "status": "PENDING",
                      "total": 250,
                      "processed": 0,
                      "outcomes": {
                        "deleted": 0,
                        "none": 0,
                        "retained_with_user": 0,
                        "ineligible_no_vendor_user": 0,
                        "failed_retryable": 0,
                        "already_deleted": 0
                      },
                      "deleted_child_verifications": 0,
                      "error": null,
                      "created_at": "2026-10-09T10:15:00Z",
                      "completed_at": null
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Kesalahan validasi — tidak ada yang dihapus. Nilai kesalahan adalah array string pesan dengan kunci berdasarkan nama kolom.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "session_numbers": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  },
                  "additionalProperties": {
                    "description": "Kunci lain: kunci `filter_*` yang bukan merupakan filter Daftar Sesi (`\"Unknown filter.\"`), atau kunci `filter_*` yang nilainya tidak dapat dibaca (dikelompokkan berdasarkan kunci `filter_*` tersebut, dengan larik pesan)."
                  }
                },
                "examples": {
                  "Missing selector": {
                    "summary": "Baik session_numbers maupun delete_all tidak diberikan",
                    "value": {
                      "session_numbers": [
                        "This field is required unless delete_all is true."
                      ]
                    }
                  },
                  "Empty list": {
                    "summary": "session_numbers adalah larik kosong",
                    "value": {
                      "session_numbers": [
                        "This list may not be empty."
                      ]
                    }
                  },
                  "Non-numeric entry": {
                    "summary": "session_numbers berisi string non-digit",
                    "value": {
                      "session_numbers": [
                        "All session_numbers must be numeric."
                      ]
                    }
                  },
                  "Privacy erasure cannot retain": {
                    "summary": "deletion_instruction bernilai privacy_erasure yang digabungkan dengan retain_face_embeddings bernilai true",
                    "value": {
                      "retain_face_embeddings": [
                        "Privacy erasure cannot retain biometric templates."
                      ]
                    }
                  },
                  "No finite retention duration": {
                    "summary": "Retensi diminta tanpa face_retention_days pada permintaan atau aplikasi",
                    "value": {
                      "detail": "A finite biometric-template retention duration is required."
                    }
                  },
                  "Unknown filter": {
                    "summary": "Kunci filter_* yang tidak dimiliki oleh List Sessions",
                    "value": {
                      "filter_reviewer": "Unknown filter."
                    }
                  },
                  "Unreadable filter value": {
                    "summary": "Nilai filter yang tidak dapat dibaca",
                    "value": {
                      "filter_date_from": [
                        "Enter a valid date."
                      ]
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Kunci API tidak ada. Kunci yang tidak ada mengembalikan `403`; kunci yang salah, dicabut, atau kedaluwarsa mengembalikan `401`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Missing or invalid API key": {
                    "summary": "Tidak ada header x-api-key, atau kunci tidak valid",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Batas laju penulisan bersama terlampaui (300 permintaan POST/PATCH/DELETE per menit per kunci API). Periksa header respons `Retry-After` dan `X-RateLimit-*` sebelum mencoba lagi.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Rate limited": {
                    "summary": "Anggaran penulisan habis",
                    "value": {
                      "detail": "Write request rate limit exceeded. You can make up to 300 requests per minute."
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "Sesi yang dipilih adalah bagian dari laporan regulasi yang telah difinalisasi. Tidak ada yang dihapus.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InFiledReportError"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST \\\n  https://verification.didit.me/v3/sessions/delete/ \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"session_numbers\": [\"1001\", \"1002\", \"1003\"]\n  }'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.batch_delete(\n    session_numbers=[\"1001\", \"1002\", \"1003\"],\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.batchDelete({\n  session_numbers: [\"1001\", \"1002\", \"1003\"],\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.BatchDelete(ctx, didit.SessionsBatchDeleteParams{\n\tSessionNumbers: didit.Some([]string{\"1001\", \"1002\", \"1003\"}),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.List;\nimport me.didit.Didit;\nimport me.didit.types.SessionsBatchDeleteParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().batchDelete(SessionsBatchDeleteParams.builder()\n        .sessionNumbers(List.of(\"1001\", \"1002\", \"1003\"))\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->sessions->batchDelete([\n    'session_numbers' => ['1001', '1002', '1003'],\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.batch_delete(session_numbers: [\"1001\", \"1002\", \"1003\"])\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.BatchDeleteAsync(new SessionsBatchDeleteParams\n{\n    SessionNumbers = new string[] { \"1001\", \"1002\", \"1003\" },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/sessions/delete/{job_id}/": {
      "get": {
        "summary": "Dapatkan tugas penghapusan sesi massal",
        "description": "Progres penghapusan sesi massal yang dijawab oleh `POST /v3/sessions/delete/` dengan `202` (lebih dari 20 sesi yang cocok, dipilih melalui `session_numbers` atau dengan `delete_all`). Lakukan polling setiap beberapa detik selama `status` masih `PENDING` atau `PROCESSING`; hentikan jika sudah `COMPLETED` atau `FAILED`.\n\nTugas ini melaporkan berapa banyak sesi yang berakhir pada setiap hasil dan berapa banyak yang telah diproses, tanpa pernah menyebutkan sesi mana saja yang dihapus. Tugas yang `FAILED` memuat alasannya di dalam `error`; sesi yang belum tersentuh masih tetap ada, jadi ulangi permintaan penghapusan untuk menghapusnya.\n\n**Autentikasi:** Kunci API di header `x-api-key`. Tugas hanya dapat dilihat oleh aplikasi yang membuatnya; `job_id` lainnya akan mengembalikan `404`. Kredensial yang hilang atau tidak valid mengembalikan `403`; API ini tidak pernah mengembalikan `401`.",
        "operationId": "get_session_deletion_job",
        "x-didit-sdk": {
          "resource": "sessions",
          "method": "retrieve_deletion_job",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Sessions"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "job_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "`job_id` yang dikembalikan bersama `202` dari `POST /v3/sessions/delete/`."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl 'https://verification.didit.me/v3/sessions/delete/JOB_ID/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.retrieve_deletion_job(\n    \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.retrieveDeletionJob(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.RetrieveDeletionJob(ctx, \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().retrieveDeletionJob(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->sessions->retrieveDeletionJob('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.retrieve_deletion_job(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.RetrieveDeletionJobAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "Pekerjaan tersebut.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SessionDeletionJob"
                },
                "examples": {
                  "Processing": {
                    "value": {
                      "job_id": "5b8f2c1e-7d3a-4f6b-9e2c-1a0d8f7e6c5b",
                      "status": "PROCESSING",
                      "total": 250,
                      "processed": 100,
                      "outcomes": {
                        "deleted": 82,
                        "none": 18,
                        "retained_with_user": 0,
                        "ineligible_no_vendor_user": 0,
                        "failed_retryable": 0,
                        "already_deleted": 0
                      },
                      "deleted_child_verifications": 0,
                      "error": null,
                      "created_at": "2026-10-09T10:15:00Z",
                      "completed_at": null
                    }
                  },
                  "Completed": {
                    "value": {
                      "job_id": "5b8f2c1e-7d3a-4f6b-9e2c-1a0d8f7e6c5b",
                      "status": "COMPLETED",
                      "total": 250,
                      "processed": 250,
                      "outcomes": {
                        "deleted": 204,
                        "none": 44,
                        "retained_with_user": 0,
                        "ineligible_no_vendor_user": 0,
                        "failed_retryable": 0,
                        "already_deleted": 2
                      },
                      "deleted_child_verifications": 0,
                      "error": null,
                      "created_at": "2026-10-09T10:15:00Z",
                      "completed_at": "2026-10-09T10:16:40Z"
                    }
                  },
                  "Failed": {
                    "value": {
                      "job_id": "5b8f2c1e-7d3a-4f6b-9e2c-1a0d8f7e6c5b",
                      "status": "FAILED",
                      "total": 250,
                      "processed": 100,
                      "outcomes": {
                        "deleted": 82,
                        "none": 18,
                        "retained_with_user": 0,
                        "ineligible_no_vendor_user": 0,
                        "failed_retryable": 0,
                        "already_deleted": 0
                      },
                      "deleted_child_verifications": 0,
                      "error": "The deletion stopped before it finished. The sessions it had not reached are still in place; repeat the request to delete them.",
                      "created_at": "2026-10-09T10:15:00Z",
                      "completed_at": "2026-10-09T10:15:52Z"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Kunci API tidak ada. Kunci yang tidak ada mengembalikan `403`; kunci yang salah, dicabut, atau kedaluwarsa mengembalikan `401`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Missing or invalid API key": {
                    "summary": "Tidak ada header x-api-key, atau kunci tidak valid",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Tidak ada tugas penghapusan dengan `job_id` ini untuk aplikasi pemanggil. Tugas hanya dapat dilihat oleh aplikasi yang membuatnya."
          }
        }
      }
    },
    "/v3/sessions/{session_id}/reviews/": {
      "get": {
        "summary": "Mencantumkan daftar peninjauan sesi dan log aktivitas",
        "description": "Mengembalikan log audit / feed aktivitas untuk sesi Verifikasi Pengguna (KYC), terbaru terlebih dahulu, dalam amplop terpaginasi (`count` / `next` / `previous` / `results`, default 50 entri per halaman).\n\nEntri feed ditulis oleh setiap pihak yang berinteraksi dengan sesi ini: keputusan manual yang dibuat melalui `PATCH /v3/session/{session_id}/update-status/` (yang mencatat `previous_status` → `new_status`), aktivitas peninjau Console (komentar yang menyebut `@email`, pengeditan data KYC/POA, unggahan/penghapusan file, perubahan tag, tampilan halaman detail), kecocokan pemantauan AML berkelanjutan, dan catatan yang ditambahkan melalui `POST` pada jalur yang sama ini. Membaca feed ini merupakan padanan di sisi API dari panel **Activity** pada tampilan sesi Didit Console.\n\nHanya sesi Verifikasi Pengguna (KYC) yang dapat diakses di sini; ID sesi Verifikasi Bisnis (KYB) mengembalikan `404`.",
        "operationId": "list_session_reviews",
        "x-didit-sdk": {
          "resource": "sessions.reviews",
          "method": "list",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Sessions"
        ],
        "parameters": [
          {
            "name": "session_id",
            "in": "path",
            "required": true,
            "description": "UUID dari sesi Verifikasi Pengguna (KYC). Harus dimiliki oleh aplikasi yang sama dengan kunci API — UUID lintas aplikasi, sesi yang dihapus, dan ID sesi Verifikasi Bisnis (KYB) semuanya mengembalikan `404`.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "8c2f3a14-7e9b-4d23-9e83-3f7d5e8a1c6d"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Ukuran halaman. Nilai default-nya `50`.",
            "schema": {
              "type": "integer",
              "default": 50,
              "example": 50
            }
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "description": "Jumlah entri yang dilewati dari awal feed (terurut). Default-nya `0`. URL `next` / `previous` dalam respons memuat nilai yang tepat untuk menyusuri feed.",
            "schema": {
              "type": "integer",
              "default": 0,
              "example": 0
            }
          },
          {
            "name": "ordering",
            "in": "query",
            "required": false,
            "description": "Urutan pengurutan. Feed data secara default menampilkan yang terbaru terlebih dahulu (`-created_at`); teruskan `created_at` untuk membacanya dari yang terlama terlebih dahulu. Nilai yang tidak dikenal diabaikan secara diam-diam (urutan default digunakan); nama kolom serializer lainnya juga diterima.",
            "schema": {
              "type": "string",
              "default": "-created_at",
              "example": "created_at"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Feed aktivitas berpaginasi, secara default diurutkan dari yang terbaru. `count` adalah jumlah total entri; `next` / `previous` adalah URL halaman siap pakai (`null` di kedua ujung). `count` bernilai `0` dengan `results` kosong berarti belum ada aktivitas yang dicatat.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "count": {
                      "type": "integer",
                      "description": "Jumlah total entri feed untuk sesi ini (di semua halaman).",
                      "example": 3
                    },
                    "next": {
                      "type": "string",
                      "nullable": true,
                      "description": "URL halaman berikutnya, atau `null` pada halaman terakhir.",
                      "example": null
                    },
                    "previous": {
                      "type": "string",
                      "nullable": true,
                      "description": "URL halaman sebelumnya, atau `null` pada halaman pertama.",
                      "example": null
                    },
                    "results": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/ReviewItem"
                      },
                      "description": "Entri feed untuk halaman ini."
                    }
                  }
                },
                "examples": {
                  "DecisionTrail": {
                    "summary": "Persetujuan manual ditambah catatan yang ditambahkan via API",
                    "value": {
                      "count": 3,
                      "next": null,
                      "previous": null,
                      "results": [
                        {
                          "uuid": "de0561bc-5583-4409-9171-1a31a4c8a5f4",
                          "activity_type": "STATUS_UPDATED",
                          "actor_display": "API Client",
                          "actor_email": null,
                          "actor_type": "API_KEY",
                          "new_status": "Approved",
                          "previous_status": "In Review",
                          "comment": "Document re-checked manually; address matches.",
                          "mentioned_emails": [],
                          "previous_value": {
                            "status": "In Review"
                          },
                          "new_value": {
                            "status": "Approved"
                          },
                          "changed_fields": [
                            "status"
                          ],
                          "metadata": null,
                          "created_at": "2026-06-12T00:19:31.918735Z"
                        },
                        {
                          "uuid": "35370f58-5098-44ee-8a06-8c9af80b2455",
                          "activity_type": "STATUS_UPDATED",
                          "actor_display": "Unknown",
                          "actor_email": null,
                          "actor_type": "CONSOLE_USER",
                          "new_status": null,
                          "previous_status": null,
                          "comment": "Note without status.",
                          "mentioned_emails": [],
                          "previous_value": null,
                          "new_value": null,
                          "changed_fields": [],
                          "metadata": null,
                          "created_at": "2026-06-12T00:18:44.504157Z"
                        },
                        {
                          "uuid": "00338f82-f1c5-4f57-8614-c49bb258af1a",
                          "activity_type": "STATUS_UPDATED",
                          "actor_display": "Unknown",
                          "actor_email": null,
                          "actor_type": "CONSOLE_USER",
                          "new_status": "In Review",
                          "previous_status": null,
                          "comment": "Flagging for manual document re-check.",
                          "mentioned_emails": [],
                          "previous_value": null,
                          "new_value": null,
                          "changed_fields": [],
                          "metadata": null,
                          "created_at": "2026-06-12T00:18:44.466537Z"
                        }
                      ]
                    }
                  },
                  "PaginatedFirstPage": {
                    "summary": "Halaman pertama dengan limit=2 — next memuat URL kelanjutan",
                    "value": {
                      "count": 4,
                      "next": "https://verification.didit.me/v3/sessions/8c2f3a14-7e9b-4d23-9e83-3f7d5e8a1c6d/reviews/?limit=2&offset=2",
                      "previous": null,
                      "results": [
                        {
                          "uuid": "de0561bc-5583-4409-9171-1a31a4c8a5f4",
                          "activity_type": "STATUS_UPDATED",
                          "actor_display": "API Client",
                          "actor_email": null,
                          "actor_type": "API_KEY",
                          "new_status": "Approved",
                          "previous_status": "In Review",
                          "comment": "Document re-checked manually; address matches.",
                          "mentioned_emails": [],
                          "previous_value": {
                            "status": "In Review"
                          },
                          "new_value": {
                            "status": "Approved"
                          },
                          "changed_fields": [
                            "status"
                          ],
                          "metadata": null,
                          "created_at": "2026-06-12T00:19:31.918735Z"
                        },
                        {
                          "uuid": "bd4e6227-bdd2-42b2-a726-1d12f785a457",
                          "activity_type": "STATUS_UPDATED",
                          "actor_display": "Unknown",
                          "actor_email": null,
                          "actor_type": "CONSOLE_USER",
                          "new_status": null,
                          "previous_status": null,
                          "comment": null,
                          "mentioned_emails": [],
                          "previous_value": null,
                          "new_value": null,
                          "changed_fields": [],
                          "metadata": null,
                          "created_at": "2026-06-12T00:18:44.540238Z"
                        }
                      ]
                    }
                  },
                  "Empty": {
                    "summary": "Sesi yang belum memiliki aktivitas tercatat",
                    "value": {
                      "count": 0,
                      "next": null,
                      "previous": null,
                      "results": []
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "`x-api-key` tidak ada, salah format, kedaluwarsa, atau dicabut. Autentikasi diperiksa sebelum pencarian sesi, sehingga kunci yang tidak ada mengembalikan `403` meskipun UUID sesi tidak ada.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "example": "You do not have permission to perform this action."
                    }
                  }
                },
                "examples": {
                  "InvalidKey": {
                    "summary": "Header x-api-key tidak ada atau tidak valid",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Tidak ada sesi Verifikasi Pengguna (KYC) dengan UUID ini yang terlihat oleh aplikasi Anda: UUID tidak ada, sesi telah dihapus, atau sesi tersebut milik aplikasi lain. ID sesi Verifikasi Bisnis (KYB) juga mengembalikan `404` di sini — feed ulasan hanya dapat diakses untuk sesi KYC.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "example": "Session not found."
                    }
                  }
                },
                "examples": {
                  "NotFound": {
                    "summary": "UUID sesi tidak dikenal, telah dihapus, atau lintas aplikasi",
                    "value": {
                      "detail": "Session not found."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Batas laju terlampaui. Periksa header respons `Retry-After` dan `X-RateLimit-*`. Lihat [Pembatasan laju](/id/integration/rate-limiting)."
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -s 'https://verification.didit.me/v3/sessions/8c2f3a14-7e9b-4d23-9e83-3f7d5e8a1c6d/reviews/?limit=50' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nfor item in client.sessions.reviews.list(\n    \"8c2f3a14-7e9b-4d23-9e83-3f7d5e8a1c6d\",\n):\n    print(item)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nfor await (const item of didit.sessions.reviews.list(\"8c2f3a14-7e9b-4d23-9e83-3f7d5e8a1c6d\")) {\n  console.log(item);\n}"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\niter := client.Sessions.Reviews.ListAutoPaging(ctx, \"8c2f3a14-7e9b-4d23-9e83-3f7d5e8a1c6d\", didit.SessionsReviewsListParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nfor (var item : client.sessions().reviews().list(\"8c2f3a14-7e9b-4d23-9e83-3f7d5e8a1c6d\")) {\n    System.out.println(item);\n}"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\nforeach ($didit->sessions->reviews->list('8c2f3a14-7e9b-4d23-9e83-3f7d5e8a1c6d') as $item) {\n    print_r($item->toArray());\n}"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.sessions.reviews.list(\"8c2f3a14-7e9b-4d23-9e83-3f7d5e8a1c6d\").auto_paging_each do |item|\n  puts item.to_h\nend"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.Sessions.Reviews.ListAsync(\"8c2f3a14-7e9b-4d23-9e83-3f7d5e8a1c6d\"))\n{\n    Console.WriteLine(JsonSerializer.Serialize(item));\n}"
          }
        ]
      },
      "post": {
        "summary": "Tambahkan catatan peninjauan ke jejak audit sesi",
        "description": "Tambahkan catatan ke umpan peninjauan / aktivitas sesi Verifikasi Pengguna (KYC). **Endpoint ini hanya mencatat entri — tidak pernah mengubah sesi.** `status` sesi dibiarkan tidak berubah, tidak ada validasi transisi status yang dijalankan, dan tidak ada webhook yang dipicu. Untuk benar-benar menyetujui, menolak, atau membuka kembali sesi (yang juga menulis entri `STATUS_UPDATED` yang diatribusikan penuh ke umpan ini), gunakan `PATCH /v3/session/{session_id}/update-status/` sebagai gantinya.\n\nKedua kolom body bersifat opsional dan objek JSON kosong diterima. `new_status` disimpan murni sebagai label pada entri dan menerima salah satu dari sepuluh nilai status sesi (peka huruf besar-kecil). Sebutan `@email` di dalam `comment` hanya disimpan sebagai teks biasa — sebutan tersebut tidak memicu notifikasi pada endpoint ini, dan `mentioned_emails` pada entri tetap kosong.\n\nCatatan tentang atribusi: entri yang dibuat di sini tidak membawa informasi pelaku. Di dalam umpan, entri menampilkan `actor_display: \"Unknown\"`, `actor_type: \"CONSOLE_USER\"`, dan `activity_type: \"STATUS_UPDATED\"` (default penyimpanan), dan kolom `user` pada body `201` bernilai `\"Unknown\"`.",
        "operationId": "create_session_review",
        "x-didit-sdk": {
          "resource": "sessions.reviews",
          "method": "create",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Sessions"
        ],
        "parameters": [
          {
            "name": "Content-Type",
            "in": "header",
            "required": false,
            "description": "Atur ke `application/json` saat mengirimkan isi JSON.",
            "schema": {
              "type": "string",
              "example": "application/json"
            }
          },
          {
            "name": "session_id",
            "in": "path",
            "required": true,
            "description": "UUID dari sesi Verifikasi Pengguna (KYC). Harus dimiliki oleh aplikasi yang sama dengan kunci API — UUID lintas aplikasi, sesi yang dihapus, dan ID sesi Verifikasi Bisnis (KYB) semuanya mengembalikan `404`.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "8c2f3a14-7e9b-4d23-9e83-3f7d5e8a1c6d"
            }
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "new_status": {
                    "type": "string",
                    "nullable": true,
                    "enum": [
                      "Not Started",
                      "In Progress",
                      "Approved",
                      "Declined",
                      "In Review",
                      "Expired",
                      "Abandoned",
                      "Kyc Expired",
                      "Resubmitted",
                      "Awaiting User"
                    ],
                    "description": "Label status opsional untuk dicatat pada entri. Menerima nilai status sesi apa pun, peka huruf besar/kecil (`\"approved\"` ditolak dengan `400`). Mencatat status di sini **tidak** mengubah status sesi yang sebenarnya — gunakan endpoint update-status untuk itu.",
                    "example": "In Review"
                  },
                  "comment": {
                    "type": "string",
                    "nullable": true,
                    "description": "Catatan teks bebas opsional (tidak ada batas panjang yang diberlakukan). Disimpan apa adanya; sebutan `@email` tidak diproses pada endpoint ini.",
                    "example": "Flagging for manual document re-check."
                  }
                }
              },
              "examples": {
                "NoteWithStatusLabel": {
                  "summary": "Catatan yang memuat label status (status sesi tidak berubah)",
                  "value": {
                    "new_status": "In Review",
                    "comment": "Flagging for manual document re-check."
                  }
                },
                "CommentOnly": {
                  "summary": "Catatan biasa tanpa label status",
                  "value": {
                    "comment": "Customer emailed an updated utility bill; awaiting upload."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Entri dicatat pada jejak audit sesi. Sesi itu sendiri tidak berubah — `status`-nya tetap memiliki nilai sebelumnya dan tidak ada webhook yang dikirim. Entri baru juga muncul di bagian atas `GET …/reviews/` (dengan `actor_display: \"Unknown\"`).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "user": {
                      "type": "string",
                      "description": "Nama tampilan penulis entri. Selalu `\"Unknown\"` untuk entri yang dibuat melalui endpoint ini, karena tidak mencatat atribusi pelaku.",
                      "example": "Unknown"
                    },
                    "new_status": {
                      "type": "string",
                      "nullable": true,
                      "enum": [
                        "Not Started",
                        "In Progress",
                        "Approved",
                        "Declined",
                        "In Review",
                        "Expired",
                        "Abandoned",
                        "Kyc Expired",
                        "Resubmitted",
                        "Awaiting User"
                      ],
                      "description": "Label status yang dicatat pada entri, atau `null` jika tidak ada yang dikirim. Status sesi yang sebenarnya tidak terpengaruh.",
                      "example": "In Review"
                    },
                    "comment": {
                      "type": "string",
                      "nullable": true,
                      "description": "Catatan yang terekam pada entri, atau `null` jika tidak ada yang dikirim.",
                      "example": "Flagging for manual document re-check."
                    },
                    "created_at": {
                      "type": "string",
                      "format": "date-time",
                      "description": "Waktu ketika entri ditulis, ISO 8601 UTC.",
                      "example": "2026-06-12T00:18:44.466537Z"
                    }
                  }
                },
                "examples": {
                  "NoteWithStatusLabel": {
                    "summary": "Catatan dengan label status",
                    "value": {
                      "user": "Unknown",
                      "new_status": "In Review",
                      "comment": "Flagging for manual document re-check.",
                      "created_at": "2026-06-12T00:18:44.466537Z"
                    }
                  },
                  "CommentOnly": {
                    "summary": "Catatan biasa",
                    "value": {
                      "user": "Unknown",
                      "new_status": null,
                      "comment": "Note without status.",
                      "created_at": "2026-06-12T00:18:44.504157Z"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Kesalahan validasi, dikembalikan sebagai peta pesan per kolom. Penyebab umumnya adalah nilai `new_status` yang bukan salah satu dari sepuluh status yang diizinkan — pemeriksaan ini peka huruf besar-kecil.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "new_status": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "example": [
                        "\"approved\" is not a valid choice."
                      ]
                    }
                  }
                },
                "examples": {
                  "InvalidStatusChoice": {
                    "summary": "Nilai status huruf kecil / tidak dikenal",
                    "value": {
                      "new_status": [
                        "\"approved\" is not a valid choice."
                      ]
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "`x-api-key` tidak ada, salah format, kedaluwarsa, atau dicabut. Autentikasi diperiksa sebelum pencarian sesi, sehingga kunci yang tidak ada mengembalikan `403` meskipun UUID sesi tidak ada.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "example": "You do not have permission to perform this action."
                    }
                  }
                },
                "examples": {
                  "InvalidKey": {
                    "summary": "Header x-api-key tidak ada atau tidak valid",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Tidak ada sesi Verifikasi Pengguna (KYC) dengan UUID ini yang terlihat oleh aplikasi Anda: UUID tidak ada, sesi telah dihapus, atau sesi tersebut milik aplikasi lain. ID sesi Verifikasi Bisnis (KYB) juga mengembalikan `404` di sini — feed ulasan hanya dapat diakses untuk sesi KYC.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "example": "Session not found."
                    }
                  }
                },
                "examples": {
                  "NotFound": {
                    "summary": "UUID sesi tidak dikenal, telah dihapus, atau lintas aplikasi",
                    "value": {
                      "detail": "Session not found."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Batas laju terlampaui. Periksa header respons `Retry-After` dan `X-RateLimit-*`. Lihat [Pembatasan laju](/id/integration/rate-limiting)."
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "# Records an audit-trail note only -- the session's status does NOT change.\ncurl -s -X POST https://verification.didit.me/v3/sessions/8c2f3a14-7e9b-4d23-9e83-3f7d5e8a1c6d/reviews/ \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"new_status\": \"In Review\",\n    \"comment\": \"Flagging for manual document re-check.\"\n  }'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.reviews.create(\n    \"8c2f3a14-7e9b-4d23-9e83-3f7d5e8a1c6d\",\n    new_status=\"In Review\",\n    comment=\"Flagging for manual document re-check.\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.reviews.create(\"8c2f3a14-7e9b-4d23-9e83-3f7d5e8a1c6d\", {\n  new_status: \"In Review\",\n  comment: \"Flagging for manual document re-check.\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.Reviews.Create(ctx, \"8c2f3a14-7e9b-4d23-9e83-3f7d5e8a1c6d\", didit.SessionsReviewsCreateParams{\n\tNewStatus: didit.Some(didit.SessionsReviewsCreateParamsNewStatus(\"In Review\")),\n\tComment:   didit.String(\"Flagging for manual document re-check.\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.SessionsReviewsCreateParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().reviews().create(\"8c2f3a14-7e9b-4d23-9e83-3f7d5e8a1c6d\", SessionsReviewsCreateParams.builder()\n        .newStatus(SessionsReviewsCreateParams.NewStatus.of(\"In Review\"))\n        .comment(\"Flagging for manual document re-check.\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->sessions->reviews->create('8c2f3a14-7e9b-4d23-9e83-3f7d5e8a1c6d', [\n    'new_status' => 'In Review',\n    'comment' => 'Flagging for manual document re-check.',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.reviews.create(\n  \"8c2f3a14-7e9b-4d23-9e83-3f7d5e8a1c6d\",\n  new_status: \"In Review\",\n  comment: \"Flagging for manual document re-check.\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.Reviews.CreateAsync(\"8c2f3a14-7e9b-4d23-9e83-3f7d5e8a1c6d\", new SessionsReviewsCreateParams\n{\n    NewStatus = new SessionsReviewsCreateParamsNewStatus(\"In Review\"),\n    Comment = \"Flagging for manual document re-check.\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/billing/balance/": {
      "get": {
        "summary": "Dapatkan saldo kredit",
        "description": "Dapatkan saldo kredit prabayar saat ini dalam USD (seluruh organisasi) ditambah konfigurasi isi otomatis. Jumlah berupa string desimal — uraikan dengan pustaka desimal.",
        "operationId": "get_billing_balance",
        "x-didit-sdk": {
          "resource": "billing",
          "method": "retrieve_balance",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Billing"
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/billing/balance/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.billing.retrieve_balance()\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.billing.retrieveBalance();\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Billing.RetrieveBalance(ctx)\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.billing().retrieveBalance();\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->billing->retrieveBalance();\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.billing.retrieve_balance\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Billing.RetrieveBalanceAsync();\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "Saldo kredit saat ini beserta konfigurasi isi ulang otomatis organisasi.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "balance",
                    "auto_refill_enabled"
                  ],
                  "properties": {
                    "balance": {
                      "type": "string",
                      "description": "Saldo kredit prabayar saat ini dalam USD, sebagai string desimal titik tetap. Berkurang saat verifikasi ditagih dan bertambah saat isi saldo diselesaikan."
                    },
                    "auto_refill_enabled": {
                      "type": "boolean",
                      "description": "Jika `true`, Didit akan secara otomatis menagih metode pembayaran yang tersimpan untuk menambahkan kredit setelah saldo melewati `auto_refill_threshold`. Dikonfigurasi dari Konsol → Penagihan."
                    },
                    "auto_refill_amount": {
                      "type": "string",
                      "nullable": true,
                      "description": "Jumlah USD yang akan ditagihkan dan ditambahkan ke saldo pada setiap isi ulang otomatis, sesuai nilai nominal. Diatur dari \\$50 hingga \\$20,000 di Console → Billing. `null` jika isi ulang otomatis dinonaktifkan atau belum diatur."
                    },
                    "auto_refill_threshold": {
                      "type": "string",
                      "nullable": true,
                      "description": "Ambang batas pemicu dalam USD. Isi saldo otomatis terpicu saat `balance` turun di bawah nilai ini. `null` saat isi saldo otomatis dinonaktifkan atau belum diatur."
                    }
                  }
                },
                "examples": {
                  "Healthy balance with auto-refill": {
                    "value": {
                      "balance": "1234.5600",
                      "auto_refill_enabled": true,
                      "auto_refill_amount": "500.00",
                      "auto_refill_threshold": "100.00"
                    }
                  },
                  "Low balance, manual top-up only": {
                    "value": {
                      "balance": "12.0000",
                      "auto_refill_enabled": false,
                      "auto_refill_amount": null,
                      "auto_refill_threshold": null
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Kunci API tidak ada, tidak valid, atau dicabut, atau kunci tersebut tidak dapat membaca data penagihan untuk organisasi ini. Kunci yang tidak ada mengembalikan `403`; kunci yang salah, dicabut, atau kedaluwarsa mengembalikan `401`.",
            "content": {
              "application/json": {
                "examples": {
                  "Forbidden": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Batas laju terlampaui; kurangi laju permintaan dan coba lagi setelah interval yang ditunjukkan dalam `Retry-After`.",
            "content": {
              "application/json": {
                "examples": {
                  "Throttled": {
                    "value": {
                      "detail": "Request was throttled. Expected available in 30 seconds."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/billing/top-up/": {
      "post": {
        "summary": "Isi saldo kredit",
        "description": "Tambahkan kredit melalui sesi Stripe Checkout yang di-hosting (**\\$50 hingga \\$20,000** per pengisian saldo). Pengisian saldo tersedia pada paket Free, Growth, dan Scale, ditambahkan pada nilai nominal tanpa diskon atau bonus, dan berlaku selama 12 bulan; kontrak tahunan Enterprise tidak dapat melakukan isi saldo. Alihkan pelanggan ke `checkout_session_url` yang dikembalikan.",
        "operationId": "billing_top_up",
        "x-didit-sdk": {
          "resource": "billing",
          "method": "top_up",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Billing"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "amount_in_dollars"
                ],
                "properties": {
                  "amount_in_dollars": {
                    "type": "number",
                    "minimum": 50,
                    "maximum": 20000,
                    "description": "Jumlah yang akan ditagihkan, dalam USD. **Harus antara 50 hingga 20.000.** Saldo menerima jumlah yang sama, tanpa diskon atau bonus. Pajak ditambahkan secara otomatis saat checkout berdasarkan alamat penagihan pelanggan."
                  },
                  "success_url": {
                    "type": "string",
                    "format": "uri",
                    "description": "URL tujuan pengalihan pelanggan oleh checkout yang di-hosting setelah pembayaran berhasil. Saat ini default-nya adalah `https://console.didit.me`. Teruskan URL yang berfungsi secara eksplisit; host default tidak tersedia. Tambahkan placeholder literal `{CHECKOUT_SESSION_ID}` jika Anda ingin checkout yang di-hosting mengganti ID sesi tersebut."
                  },
                  "cancel_url": {
                    "type": "string",
                    "format": "uri",
                    "description": "URL tujuan pengalihan pelanggan oleh checkout yang di-hosting saat mereka membatalkan atau menutup jendela Checkout. Saat ini default-nya adalah `https://console.didit.me`. Teruskan URL yang berfungsi secara eksplisit; host default tidak tersedia."
                  }
                }
              },
              "examples": {
                "Minimum top-up": {
                  "value": {
                    "amount_in_dollars": 50
                  }
                },
                "Custom amount with redirects": {
                  "value": {
                    "amount_in_dollars": 500,
                    "success_url": "https://yourapp.com/billing/top-up/success",
                    "cancel_url": "https://yourapp.com/billing/top-up/cancel"
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://verification.didit.me/v3/billing/top-up/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"amount_in_dollars\": 500,\n    \"success_url\": \"https://yourapp.com/billing/success\",\n    \"cancel_url\": \"https://yourapp.com/billing/cancel\"\n  }'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.billing.top_up(\n    amount_in_dollars=50.0,\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.billing.topUp({\n  amount_in_dollars: 50.0,\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Billing.TopUp(ctx, didit.BillingTopUpParams{\n\tAmountInDollars: 50.0,\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.BillingTopUpParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.billing().topUp(BillingTopUpParams.builder()\n        .amountInDollars(50.0)\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->billing->topUp([\n    'amount_in_dollars' => 50.0,\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.billing.top_up(amount_in_dollars: 50.0)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Billing.TopUpAsync(new BillingTopUpParams\n{\n    AmountInDollars = 50.0,\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "Sesi checkout yang di-hosting dibuat. Arahkan pengguna ke `checkout_session_url` untuk menyelesaikan pembayaran.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "checkout_session_id",
                    "checkout_session_url"
                  ],
                  "properties": {
                    "checkout_session_id": {
                      "type": "string",
                      "description": "Pengidentifikasi sesi checkout yang di-hosting (misalnya `cs_test_a1B2c3...`). Berguna untuk rekonsiliasi sisi server."
                    },
                    "checkout_session_url": {
                      "type": "string",
                      "format": "uri",
                      "description": "URL halaman pembayaran yang di-hosting sekali pakai. Arahkan pelanggan ke sini untuk menyelesaikan pembayaran."
                    }
                  }
                },
                "examples": {
                  "Created": {
                    "value": {
                      "checkout_session_id": "cs_test_a1B2c3D4e5F6g7H8i9J0",
                      "checkout_session_url": "https://checkout.example.com/c/pay/cs_test_a1B2c3D4e5F6g7H8i9J0"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Payload tidak valid: jumlah hilang, bukan angka, di bawah minimum \\$50 atau di atas maksimum \\$20,000, atau organisasi menggunakan kontrak tahunan Enterprise. Body kesalahan berupa array JSON.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing amount": {
                    "value": [
                      "amount_in_dollars is required."
                    ]
                  },
                  "Not a number": {
                    "value": [
                      "amount_in_dollars must be a number."
                    ]
                  },
                  "Below minimum": {
                    "value": [
                      "Amount must be at least $50."
                    ]
                  },
                  "Above maximum": {
                    "value": [
                      "Amount must be at most $20,000."
                    ]
                  },
                  "Annual plan": {
                    "value": [
                      "You have an annual plan. Contact your account manager to top up."
                    ]
                  }
                }
              }
            }
          },
          "403": {
            "description": "Kunci API tidak ada, tidak valid, atau dicabut, atau kunci tidak dapat membuat sesi isi saldo untuk organisasi ini. Kunci yang tidak ada mengembalikan `403`; kunci yang salah, dicabut, atau kedaluwarsa mengembalikan `401`.",
            "content": {
              "application/json": {
                "examples": {
                  "Forbidden": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Batas laju terlampaui; kurangi laju permintaan dan coba lagi setelah interval yang ditunjukkan dalam `Retry-After`.",
            "content": {
              "application/json": {
                "examples": {
                  "Throttled": {
                    "value": {
                      "detail": "Request was throttled. Expected available in 30 seconds."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/webhook/destinations/": {
      "get": {
        "summary": "Daftar tujuan webhook",
        "description": "Daftar semua tujuan webhook (array tanpa paginasi, terlama lebih dahulu). Setiap item memuat konfigurasi tujuan, metrik pengirimannya selama 30 hari terakhir (`metrics_window_days`) dengan satu entri `daily_points` per hari, dan statusnya (`health_status`, `failing_streak`, `failing_since`, `last_success_at`). Daftar ini tidak memiliki objek `summary` dan tidak pernah menyertakan rahasia penandatanganan: setiap item hanya menampilkan `secret_last4`. Ambil satu tujuan (`GET /v3/webhook/destinations/{destination_uuid}/`) untuk membaca `secret_shared_key`.",
        "operationId": "list_webhook_destinations",
        "x-didit-sdk": {
          "resource": "webhooks.destinations",
          "method": "list",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Webhook"
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/webhook/destinations/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.webhooks.destinations.list()\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.webhooks.destinations.list();\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Webhooks.Destinations.List(ctx)\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.webhooks().destinations().list();\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->webhooks->destinations->list();\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.webhooks.destinations.list.each do |item|\n  puts item.to_h\nend"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Webhooks.Destinations.ListAsync();\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "Daftar tujuan webhook (tanpa paginasi, terlama lebih dahulu).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "uuid": {
                        "type": "string",
                        "format": "uuid",
                        "description": "Pengidentifikasi tujuan yang stabil; gunakan sebagai `{destination_uuid}` untuk pembaruan/penghapusan."
                      },
                      "label": {
                        "type": "string",
                        "description": "Nama yang mudah dibaca manusia yang ditampilkan di Console."
                      },
                      "url": {
                        "type": "string",
                        "format": "uri",
                        "description": "URL tujuan yang menerima permintaan `POST` dengan payload webhook."
                      },
                      "enabled": {
                        "type": "boolean",
                        "description": "Jika `false`, Didit tidak melakukan pengiriman ke tujuan ini tanpa menampilkan peringatan."
                      },
                      "webhook_version": {
                        "type": "string",
                        "enum": [
                          "v1",
                          "v2",
                          "v3"
                        ],
                        "description": "Versi skema payload yang dikirim ke tujuan ini. `v3` adalah format saat ini/yang direkomendasikan."
                      },
                      "subscribed_events": {
                        "$ref": "#/components/schemas/WebhookSubscribedEvents"
                      },
                      "subscribed_events_count": {
                        "type": "integer",
                        "description": "Panjang `subscribed_events` yang di-cache, berguna untuk rendering UI."
                      },
                      "deliveries_count": {
                        "type": "integer",
                        "description": "Upaya pengiriman (termasuk percobaan ulang) yang dilakukan ke tujuan ini dalam 30 hari terakhir."
                      },
                      "failed_deliveries_count": {
                        "type": "integer",
                        "description": "Upaya pengiriman dalam 30 hari terakhir yang dijawab tujuan dengan HTTP 400 ke atas, atau tidak dijawab (waktu habis, koneksi ditolak, atau alamat diblokir)."
                      },
                      "average_response_time_ms": {
                        "type": "integer",
                        "nullable": true,
                        "description": "Waktu respons rata-rata dalam milidetik selama 30 hari terakhir, dibulatkan ke bilangan bulat. `null` jika tidak ada pengiriman dalam jangka waktu tersebut."
                      },
                      "error_rate_percentage": {
                        "type": "integer",
                        "description": "`round(failed_deliveries_count / deliveries_count * 100)` selama 30 hari terakhir; `0` saat tidak ada pengiriman."
                      },
                      "last_delivery_at": {
                        "type": "string",
                        "format": "date-time",
                        "nullable": true,
                        "description": "Cap waktu upaya pengiriman terbaru (berhasil atau gagal). `null` jika belum pernah dikirimkan."
                      },
                      "metrics_window_days": {
                        "type": "integer",
                        "description": "Panjang dalam hari dari jendela yang dicakup oleh `deliveries_count`, `failed_deliveries_count`, `average_response_time_ms`, `error_rate_percentage`, dan `daily_points`. Selalu `30`."
                      },
                      "health_status": {
                        "type": "string",
                        "enum": [
                          "healthy",
                          "degraded",
                          "failing"
                        ],
                        "description": "Status pengiriman. `failing`: 3 event berturut-turut atau lebih gagal pada upaya pengiriman pertamanya sejak tujuan terakhir kali merespons dengan berhasil (lihat `failing_streak`). `degraded`: tidak gagal (failing), tetapi upaya pengiriman gagal dalam 24 jam terakhir dan tidak ada upaya berikutnya yang berhasil mengirimkan event tersebut; percobaan ulang atau pengiriman ulang yang berhasil menyelesaikannya akan menghapus status ini. `healthy`: tidak keduanya. Independen dari `enabled`. Upaya yang gagal adalah upaya yang direspons dengan HTTP 400 ke atas, atau tidak direspons sama sekali."
                      },
                      "failing_streak": {
                        "type": "integer",
                        "description": "Berapa banyak event berturut-turut yang gagal pada upaya pengiriman pertamanya sejak tujuan terakhir kali merespons dengan berhasil, dalam 30 hari terakhir. Coba lagi tidak dihitung, dan setiap upaya yang berhasil, termasuk coba lagi atau pengiriman ulang, mengakhiri rentetan tersebut. `0` jika tidak ada event yang gagal sejak keberhasilan terakhir."
                      },
                      "failing_since": {
                        "type": "string",
                        "format": "date-time",
                        "nullable": true,
                        "description": "Waktu ketika upaya gagal pertama dari `failing_streak` saat ini dilakukan. `null` jika `failing_streak` bernilai `0`."
                      },
                      "last_success_at": {
                        "type": "string",
                        "format": "date-time",
                        "nullable": true,
                        "description": "Waktu ketika tujuan terakhir kali merespons pengiriman dengan status HTTP di bawah 400, dalam 30 hari terakhir. `null` jika tidak merespons dalam rentang waktu tersebut."
                      },
                      "environment": {
                        "type": "string",
                        "enum": [
                          "live",
                          "sandbox"
                        ],
                        "description": "Lingkungan aplikasi yang memiliki tujuan tersebut."
                      },
                      "daily_points": {
                        "type": "array",
                        "description": "Satu entri per hari UTC dalam 30 hari terakhir, yang terlama terlebih dahulu, termasuk hari-hari tanpa pengiriman. Menghitung setiap upaya, termasuk coba lagi.",
                        "items": {
                          "type": "object",
                          "properties": {
                            "date": {
                              "type": "string",
                              "format": "date",
                              "description": "Hari UTC."
                            },
                            "total_deliveries": {
                              "type": "integer",
                              "description": "Upaya pengiriman yang dilakukan pada hari tersebut."
                            },
                            "failed_deliveries": {
                              "type": "integer",
                              "description": "Percobaan yang dilakukan pada hari itu yang dijawab dengan HTTP 400 ke atas, atau tidak dijawab sama sekali."
                            }
                          }
                        }
                      },
                      "secret_last4": {
                        "type": "string",
                        "description": "Empat karakter terakhir dari rahasia penandatanganan tujuan saat ini, sehingga Anda dapat membedakan rahasia. Tidak cukup untuk memverifikasi tanda tangan."
                      },
                      "created_by_email": {
                        "type": "string",
                        "nullable": true,
                        "description": "Email anggota Business Console yang membuat tujuan. `null` untuk tujuan yang dibuat dengan kunci API."
                      },
                      "created_by_name": {
                        "type": "string",
                        "nullable": true,
                        "description": "Nama anggota Business Console yang membuat tujuan. Bernilai `null` untuk tujuan yang dibuat dengan kunci API."
                      },
                      "created_at": {
                        "type": "string",
                        "format": "date-time"
                      },
                      "updated_at": {
                        "type": "string",
                        "format": "date-time"
                      }
                    }
                  }
                },
                "examples": {
                  "Two destinations": {
                    "value": [
                      {
                        "uuid": "11111111-2222-3333-4444-555555555555",
                        "label": "Production session webhooks",
                        "url": "https://yourapp.com/webhooks/didit",
                        "enabled": true,
                        "webhook_version": "v3",
                        "subscribed_events": [
                          "status.updated",
                          "data.updated"
                        ],
                        "subscribed_events_count": 2,
                        "deliveries_count": 12453,
                        "failed_deliveries_count": 14,
                        "average_response_time_ms": 187,
                        "error_rate_percentage": 0,
                        "last_delivery_at": "2026-05-17T09:21:18Z",
                        "metrics_window_days": 30,
                        "health_status": "healthy",
                        "failing_streak": 0,
                        "failing_since": null,
                        "last_success_at": "2026-05-17T09:21:18Z",
                        "environment": "live",
                        "daily_points": [
                          {
                            "date": "2026-04-18",
                            "total_deliveries": 415,
                            "failed_deliveries": 0
                          },
                          {
                            "date": "2026-04-19",
                            "total_deliveries": 415,
                            "failed_deliveries": 0
                          },
                          {
                            "date": "2026-04-20",
                            "total_deliveries": 415,
                            "failed_deliveries": 0
                          },
                          {
                            "date": "2026-04-21",
                            "total_deliveries": 415,
                            "failed_deliveries": 0
                          },
                          {
                            "date": "2026-04-22",
                            "total_deliveries": 415,
                            "failed_deliveries": 0
                          },
                          {
                            "date": "2026-04-23",
                            "total_deliveries": 415,
                            "failed_deliveries": 0
                          },
                          {
                            "date": "2026-04-24",
                            "total_deliveries": 415,
                            "failed_deliveries": 9
                          },
                          {
                            "date": "2026-04-25",
                            "total_deliveries": 415,
                            "failed_deliveries": 0
                          },
                          {
                            "date": "2026-04-26",
                            "total_deliveries": 415,
                            "failed_deliveries": 0
                          },
                          {
                            "date": "2026-04-27",
                            "total_deliveries": 415,
                            "failed_deliveries": 0
                          },
                          {
                            "date": "2026-04-28",
                            "total_deliveries": 415,
                            "failed_deliveries": 0
                          },
                          {
                            "date": "2026-04-29",
                            "total_deliveries": 415,
                            "failed_deliveries": 0
                          },
                          {
                            "date": "2026-04-30",
                            "total_deliveries": 415,
                            "failed_deliveries": 0
                          },
                          {
                            "date": "2026-05-01",
                            "total_deliveries": 415,
                            "failed_deliveries": 0
                          },
                          {
                            "date": "2026-05-02",
                            "total_deliveries": 415,
                            "failed_deliveries": 0
                          },
                          {
                            "date": "2026-05-03",
                            "total_deliveries": 415,
                            "failed_deliveries": 0
                          },
                          {
                            "date": "2026-05-04",
                            "total_deliveries": 415,
                            "failed_deliveries": 0
                          },
                          {
                            "date": "2026-05-05",
                            "total_deliveries": 415,
                            "failed_deliveries": 0
                          },
                          {
                            "date": "2026-05-06",
                            "total_deliveries": 415,
                            "failed_deliveries": 0
                          },
                          {
                            "date": "2026-05-07",
                            "total_deliveries": 415,
                            "failed_deliveries": 0
                          },
                          {
                            "date": "2026-05-08",
                            "total_deliveries": 415,
                            "failed_deliveries": 0
                          },
                          {
                            "date": "2026-05-09",
                            "total_deliveries": 415,
                            "failed_deliveries": 5
                          },
                          {
                            "date": "2026-05-10",
                            "total_deliveries": 415,
                            "failed_deliveries": 0
                          },
                          {
                            "date": "2026-05-11",
                            "total_deliveries": 415,
                            "failed_deliveries": 0
                          },
                          {
                            "date": "2026-05-12",
                            "total_deliveries": 415,
                            "failed_deliveries": 0
                          },
                          {
                            "date": "2026-05-13",
                            "total_deliveries": 415,
                            "failed_deliveries": 0
                          },
                          {
                            "date": "2026-05-14",
                            "total_deliveries": 415,
                            "failed_deliveries": 0
                          },
                          {
                            "date": "2026-05-15",
                            "total_deliveries": 416,
                            "failed_deliveries": 0
                          },
                          {
                            "date": "2026-05-16",
                            "total_deliveries": 416,
                            "failed_deliveries": 0
                          },
                          {
                            "date": "2026-05-17",
                            "total_deliveries": 416,
                            "failed_deliveries": 0
                          }
                        ],
                        "secret_last4": "0xnQ",
                        "created_by_email": null,
                        "created_by_name": null,
                        "created_at": "2026-01-04T08:00:00Z",
                        "updated_at": "2026-04-22T14:09:11Z"
                      },
                      {
                        "uuid": "22222222-3333-4444-5555-666666666666",
                        "label": "Staging mirror",
                        "url": "https://staging.yourapp.com/webhooks/didit",
                        "enabled": false,
                        "webhook_version": "v3",
                        "subscribed_events": [
                          "status.updated"
                        ],
                        "subscribed_events_count": 1,
                        "deliveries_count": 0,
                        "failed_deliveries_count": 0,
                        "average_response_time_ms": null,
                        "error_rate_percentage": 0,
                        "last_delivery_at": null,
                        "metrics_window_days": 30,
                        "health_status": "healthy",
                        "failing_streak": 0,
                        "failing_since": null,
                        "last_success_at": null,
                        "environment": "live",
                        "daily_points": [
                          {
                            "date": "2026-04-18",
                            "total_deliveries": 0,
                            "failed_deliveries": 0
                          },
                          {
                            "date": "2026-04-19",
                            "total_deliveries": 0,
                            "failed_deliveries": 0
                          },
                          {
                            "date": "2026-04-20",
                            "total_deliveries": 0,
                            "failed_deliveries": 0
                          },
                          {
                            "date": "2026-04-21",
                            "total_deliveries": 0,
                            "failed_deliveries": 0
                          },
                          {
                            "date": "2026-04-22",
                            "total_deliveries": 0,
                            "failed_deliveries": 0
                          },
                          {
                            "date": "2026-04-23",
                            "total_deliveries": 0,
                            "failed_deliveries": 0
                          },
                          {
                            "date": "2026-04-24",
                            "total_deliveries": 0,
                            "failed_deliveries": 0
                          },
                          {
                            "date": "2026-04-25",
                            "total_deliveries": 0,
                            "failed_deliveries": 0
                          },
                          {
                            "date": "2026-04-26",
                            "total_deliveries": 0,
                            "failed_deliveries": 0
                          },
                          {
                            "date": "2026-04-27",
                            "total_deliveries": 0,
                            "failed_deliveries": 0
                          },
                          {
                            "date": "2026-04-28",
                            "total_deliveries": 0,
                            "failed_deliveries": 0
                          },
                          {
                            "date": "2026-04-29",
                            "total_deliveries": 0,
                            "failed_deliveries": 0
                          },
                          {
                            "date": "2026-04-30",
                            "total_deliveries": 0,
                            "failed_deliveries": 0
                          },
                          {
                            "date": "2026-05-01",
                            "total_deliveries": 0,
                            "failed_deliveries": 0
                          },
                          {
                            "date": "2026-05-02",
                            "total_deliveries": 0,
                            "failed_deliveries": 0
                          },
                          {
                            "date": "2026-05-03",
                            "total_deliveries": 0,
                            "failed_deliveries": 0
                          },
                          {
                            "date": "2026-05-04",
                            "total_deliveries": 0,
                            "failed_deliveries": 0
                          },
                          {
                            "date": "2026-05-05",
                            "total_deliveries": 0,
                            "failed_deliveries": 0
                          },
                          {
                            "date": "2026-05-06",
                            "total_deliveries": 0,
                            "failed_deliveries": 0
                          },
                          {
                            "date": "2026-05-07",
                            "total_deliveries": 0,
                            "failed_deliveries": 0
                          },
                          {
                            "date": "2026-05-08",
                            "total_deliveries": 0,
                            "failed_deliveries": 0
                          },
                          {
                            "date": "2026-05-09",
                            "total_deliveries": 0,
                            "failed_deliveries": 0
                          },
                          {
                            "date": "2026-05-10",
                            "total_deliveries": 0,
                            "failed_deliveries": 0
                          },
                          {
                            "date": "2026-05-11",
                            "total_deliveries": 0,
                            "failed_deliveries": 0
                          },
                          {
                            "date": "2026-05-12",
                            "total_deliveries": 0,
                            "failed_deliveries": 0
                          },
                          {
                            "date": "2026-05-13",
                            "total_deliveries": 0,
                            "failed_deliveries": 0
                          },
                          {
                            "date": "2026-05-14",
                            "total_deliveries": 0,
                            "failed_deliveries": 0
                          },
                          {
                            "date": "2026-05-15",
                            "total_deliveries": 0,
                            "failed_deliveries": 0
                          },
                          {
                            "date": "2026-05-16",
                            "total_deliveries": 0,
                            "failed_deliveries": 0
                          },
                          {
                            "date": "2026-05-17",
                            "total_deliveries": 0,
                            "failed_deliveries": 0
                          }
                        ],
                        "secret_last4": "k9Qe",
                        "created_by_email": "reviewer@example.com",
                        "created_by_name": "Example Reviewer",
                        "created_at": "2026-03-12T10:15:02Z",
                        "updated_at": "2026-03-12T10:15:02Z"
                      }
                    ]
                  }
                }
              }
            }
          },
          "403": {
            "description": "Kunci API tidak ada, format salah, kedaluwarsa, atau memiliki cakupan untuk aplikasi yang berbeda. Kunci yang tidak ada mengembalikan `403`; kunci yang salah, dicabut, atau kedaluwarsa mengembalikan `401`.",
            "content": {
              "application/json": {
                "examples": {
                  "Forbidden": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Batas laju terlampaui; lakukan back off dan coba lagi.",
            "content": {
              "application/json": {
                "examples": {
                  "Throttled": {
                    "value": {
                      "detail": "Request was throttled. Expected available in 30 seconds."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      },
      "post": {
        "summary": "Buat tujuan webhook",
        "description": "Buat tujuan webhook. Respons mencakup rahasia penandatanganan HMAC `secret_shared_key` yang dibuat secara otomatis (juga dapat dibaca nanti melalui `GET /v3/webhook/destinations/{destination_uuid}/`). Selalu kirim `subscribed_events` dengan setidaknya satu event webhook (tanpa karakter wildcard): daftar kosong eksplisit akan ditolak dengan 400, dan meniadakan kolom ini akan membuat tujuan yang tidak berlangganan apa pun, yang tidak akan pernah menerima webhook. Pasangan `(application, url)` harus unik di antara tujuan milik aplikasi.",
        "operationId": "create_webhook_destination",
        "x-didit-sdk": {
          "resource": "webhooks.destinations",
          "method": "create",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Webhook"
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://verification.didit.me/v3/webhook/destinations/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"label\": \"Production session webhooks\",\n    \"url\": \"https://yourapp.com/webhooks/didit\",\n    \"webhook_version\": \"v3\",\n    \"subscribed_events\": [\"status.updated\", \"data.updated\"]\n  }'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.webhooks.destinations.create(\n    label=\"Production session webhooks\",\n    url=\"https://yourapp.com/webhooks/didit\",\n    webhook_version=\"v3\",\n    subscribed_events=[\"status.updated\", \"data.updated\"],\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.webhooks.destinations.create({\n  label: \"Production session webhooks\",\n  url: \"https://yourapp.com/webhooks/didit\",\n  webhook_version: \"v3\",\n  subscribed_events: [\"status.updated\", \"data.updated\"],\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Webhooks.Destinations.Create(ctx, didit.WebhooksDestinationsCreateParams{\n\tLabel:            \"Production session webhooks\",\n\tURL:              \"https://yourapp.com/webhooks/didit\",\n\tWebhookVersion:   didit.Some(didit.WebhooksDestinationsCreateParamsWebhookVersion(\"v3\")),\n\tSubscribedEvents: didit.Some([]didit.WebhookEvent{didit.WebhookEvent(\"status.updated\"), didit.WebhookEvent(\"data.updated\")}),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.List;\nimport me.didit.Didit;\nimport me.didit.types.WebhookEvent;\nimport me.didit.types.WebhooksDestinationsCreateParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.webhooks().destinations().create(WebhooksDestinationsCreateParams.builder()\n        .label(\"Production session webhooks\")\n        .url(\"https://yourapp.com/webhooks/didit\")\n        .webhookVersion(WebhooksDestinationsCreateParams.WebhookVersion.of(\"v3\"))\n        .subscribedEvents(List.of(WebhookEvent.of(\"status.updated\"), WebhookEvent.of(\"data.updated\")))\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->webhooks->destinations->create([\n    'label' => 'Production session webhooks',\n    'url' => 'https://yourapp.com/webhooks/didit',\n    'webhook_version' => 'v3',\n    'subscribed_events' => ['status.updated', 'data.updated'],\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.webhooks.destinations.create(\n  label: \"Production session webhooks\",\n  url: \"https://yourapp.com/webhooks/didit\",\n  webhook_version: \"v3\",\n  subscribed_events: [\"status.updated\", \"data.updated\"]\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Webhooks.Destinations.CreateAsync(new WebhooksDestinationsCreateParams\n{\n    Label = \"Production session webhooks\",\n    Url = \"https://yourapp.com/webhooks/didit\",\n    WebhookVersion = new WebhooksDestinationsCreateParamsWebhookVersion(\"v3\"),\n    SubscribedEvents = new WebhookEvent[] { \"status.updated\", \"data.updated\" },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "label",
                  "url"
                ],
                "properties": {
                  "label": {
                    "type": "string",
                    "maxLength": 255,
                    "description": "Nama yang mudah dibaca manusia yang ditampilkan di Console → Webhooks. Membantu membedakan tujuan ketika Anda memiliki beberapa (mis. \"Prod\", \"Staging mirror\")."
                  },
                  "url": {
                    "type": "string",
                    "format": "uri",
                    "description": "URL HTTPS yang akan menerima permintaan `POST`. Harus unik di antara tujuan aplikasi. Gunakan endpoint yang stabil dan diperkuat: Didit mencoba lagi pengiriman yang gagal dengan jadwal backoff.",
                    "maxLength": 2000
                  },
                  "enabled": {
                    "type": "boolean",
                    "default": true,
                    "description": "Jika `false`, tujuan disimpan tetapi Didit tidak akan mengirim webhook apa pun ke sana. Berguna untuk konfigurasi staging yang ingin Anda simpan sementara."
                  },
                  "webhook_version": {
                    "type": "string",
                    "enum": [
                      "v1",
                      "v2",
                      "v3"
                    ],
                    "description": "Versi skema payload yang akan dikirim oleh Didit. `v3` adalah format saat ini/yang direkomendasikan; versi yang lebih lama dipertahankan untuk kompatibilitas mundur dengan integrasi lama."
                  },
                  "subscribed_events": {
                    "allOf": [
                      {
                        "$ref": "#/components/schemas/WebhookSubscribedEvents"
                      }
                    ],
                    "description": "Event untuk dikirimkan. Secara praktis wajib: `[]` eksplisit ditolak dengan 400, dan tidak menyertakan kolom ini akan membuat tujuan tanpa langganan yang tidak menerima apa pun."
                  }
                }
              },
              "examples": {
                "session_updates": {
                  "summary": "Pembaruan data dan status sesi",
                  "value": {
                    "label": "Production session webhooks",
                    "url": "https://yourapp.com/webhooks/didit",
                    "webhook_version": "v3",
                    "subscribed_events": [
                      "status.updated",
                      "data.updated"
                    ]
                  }
                },
                "transaction_updates": {
                  "summary": "Pembaruan pemantauan transaksi",
                  "value": {
                    "label": "Transaction monitoring webhooks",
                    "url": "https://yourapp.com/webhooks/didit-transactions",
                    "webhook_version": "v3",
                    "subscribed_events": [
                      "transaction.created",
                      "transaction.status.updated"
                    ]
                  }
                },
                "entity_updates": {
                  "summary": "Pembaruan entitas Pengguna dan Bisnis",
                  "value": {
                    "label": "Entity lifecycle webhooks",
                    "url": "https://yourapp.com/webhooks/didit-entities",
                    "webhook_version": "v3",
                    "subscribed_events": [
                      "user.status.updated",
                      "user.data.updated",
                      "business.status.updated",
                      "business.data.updated",
                      "activity.created"
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Tujuan dibuat. `secret_shared_key` adalah rahasia penandatanganan HMAC — simpan sekarang.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "uuid": {
                      "type": "string",
                      "format": "uuid",
                      "description": "Pengidentifikasi tujuan yang stabil. Gunakan sebagai `{destination_uuid}` dalam panggilan berikutnya."
                    },
                    "label": {
                      "type": "string"
                    },
                    "url": {
                      "type": "string",
                      "format": "uri"
                    },
                    "enabled": {
                      "type": "boolean"
                    },
                    "webhook_version": {
                      "type": "string",
                      "enum": [
                        "v1",
                        "v2",
                        "v3"
                      ]
                    },
                    "secret_shared_key": {
                      "type": "string",
                      "description": "Rahasia penandatanganan HMAC yang dibuat secara otomatis dan terikat ke tujuan ini (token 43 karakter yang aman untuk URL). Gunakan ini untuk memverifikasi header tanda tangan pada webhook yang masuk. Selalu dikembalikan lengkap untuk pemanggil dengan kunci API; pengguna Console memerlukan izin `read:webhooks`, jika tidak, mereka melihat string kosong."
                    },
                    "secret_last4": {
                      "type": "string",
                      "description": "Empat karakter terakhir dari rahasia penandatanganan tujuan saat ini, sehingga Anda dapat membedakan rahasia. Tidak cukup untuk memverifikasi tanda tangan."
                    },
                    "previous_secret_expires_at": {
                      "type": "string",
                      "format": "date-time",
                      "nullable": true,
                      "description": "Ditetapkan selama 24 jam setelah rahasia penandatanganan tujuan dirotasi di Business Console. Hingga waktu ini, setiap pengiriman ke tujuan juga membawa `X-Signature-Previous`, `X-Signature-V2-Previous`, dan `X-Signature-Simple-Previous`, yang dibuat dengan rahasia yang diganti (lihat [Verifikasi tanda tangan](/id/integration/webhooks#verifikasi-tanda-tangan)). `null` jika tidak ada rotasi yang terjadi dalam 24 jam terakhir."
                    },
                    "subscribed_events": {
                      "$ref": "#/components/schemas/WebhookSubscribedEvents"
                    },
                    "created_by_email": {
                      "type": "string",
                      "nullable": true,
                      "description": "Email anggota Business Console yang membuat tujuan. `null` untuk tujuan yang dibuat dengan kunci API."
                    },
                    "created_by_name": {
                      "type": "string",
                      "nullable": true,
                      "description": "Nama anggota Business Console yang membuat tujuan. Bernilai `null` untuk tujuan yang dibuat dengan kunci API."
                    },
                    "created_at": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "updated_at": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "health_status": {
                      "type": "string",
                      "enum": [
                        "healthy",
                        "degraded",
                        "failing"
                      ],
                      "description": "Status pengiriman. `failing`: 3 event berturut-turut atau lebih gagal pada upaya pengiriman pertamanya sejak tujuan terakhir kali merespons dengan berhasil (lihat `failing_streak`). `degraded`: tidak gagal (failing), tetapi upaya pengiriman gagal dalam 24 jam terakhir dan tidak ada upaya berikutnya yang berhasil mengirimkan event tersebut; percobaan ulang atau pengiriman ulang yang berhasil menyelesaikannya akan menghapus status ini. `healthy`: tidak keduanya. Independen dari `enabled`. Upaya yang gagal adalah upaya yang direspons dengan HTTP 400 ke atas, atau tidak direspons sama sekali."
                    },
                    "failing_streak": {
                      "type": "integer",
                      "description": "Berapa banyak event berturut-turut yang gagal pada upaya pengiriman pertamanya sejak tujuan terakhir kali merespons dengan berhasil, dalam 30 hari terakhir. Coba lagi tidak dihitung, dan setiap upaya yang berhasil, termasuk coba lagi atau pengiriman ulang, mengakhiri rentetan tersebut. `0` jika tidak ada event yang gagal sejak keberhasilan terakhir."
                    },
                    "failing_since": {
                      "type": "string",
                      "format": "date-time",
                      "nullable": true,
                      "description": "Waktu ketika upaya gagal pertama dari `failing_streak` saat ini dilakukan. `null` jika `failing_streak` bernilai `0`."
                    },
                    "last_success_at": {
                      "type": "string",
                      "format": "date-time",
                      "nullable": true,
                      "description": "Waktu ketika tujuan terakhir kali merespons pengiriman dengan status HTTP di bawah 400, dalam 30 hari terakhir. `null` jika tidak merespons dalam rentang waktu tersebut."
                    },
                    "environment": {
                      "type": "string",
                      "enum": [
                        "live",
                        "sandbox"
                      ],
                      "description": "Lingkungan aplikasi yang memiliki tujuan tersebut."
                    },
                    "summary": {
                      "type": "object",
                      "description": "Metrik pengiriman selama `metrics_window_days` (30) hari terakhir. `last_delivery_at` adalah upaya paling baru, kapan pun upaya tersebut dilakukan.",
                      "properties": {
                        "total_deliveries": {
                          "type": "integer"
                        },
                        "failed_deliveries": {
                          "type": "integer"
                        },
                        "error_rate_percentage": {
                          "type": "integer"
                        },
                        "min_response_time_ms": {
                          "type": "integer",
                          "nullable": true
                        },
                        "avg_response_time_ms": {
                          "type": "integer",
                          "nullable": true
                        },
                        "max_response_time_ms": {
                          "type": "integer",
                          "nullable": true
                        },
                        "last_delivery_at": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true
                        },
                        "metrics_window_days": {
                          "type": "integer",
                          "description": "Panjang dalam hari dari jendela yang dicakup oleh metrik ringkasan lainnya. Selalu `30`."
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "Created": {
                    "value": {
                      "uuid": "11111111-2222-3333-4444-555555555555",
                      "label": "Production session webhooks",
                      "url": "https://yourapp.com/webhooks/didit",
                      "enabled": true,
                      "webhook_version": "v3",
                      "secret_shared_key": "tno2NTeRC1ZK3sBOYlBJDyEzBVENl3pQ1AcZyAW0xnQ",
                      "secret_last4": "0xnQ",
                      "previous_secret_expires_at": null,
                      "subscribed_events": [
                        "status.updated",
                        "data.updated"
                      ],
                      "created_by_email": null,
                      "created_by_name": null,
                      "created_at": "2026-05-17T10:00:00Z",
                      "updated_at": "2026-05-17T10:00:00Z",
                      "health_status": "healthy",
                      "failing_streak": 0,
                      "failing_since": null,
                      "last_success_at": null,
                      "environment": "live",
                      "summary": {
                        "total_deliveries": 0,
                        "failed_deliveries": 0,
                        "error_rate_percentage": 0,
                        "min_response_time_ms": null,
                        "avg_response_time_ms": null,
                        "max_response_time_ms": null,
                        "last_delivery_at": null,
                        "metrics_window_days": 30
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validasi gagal — biasanya URL duplikat, `subscribed_events` tidak ada/tidak valid, atau nama event tidak dikenal.",
            "content": {
              "application/json": {
                "examples": {
                  "Duplicate URL": {
                    "value": {
                      "url": [
                        "This webhook destination already exists for the application."
                      ]
                    }
                  },
                  "Empty events list": {
                    "value": {
                      "subscribed_events": [
                        "At least one subscribed event is required."
                      ]
                    }
                  },
                  "Unknown event": {
                    "value": {
                      "subscribed_events": [
                        "Unsupported webhook events: foo.bar"
                      ]
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Kunci API tidak ada, format salah, kedaluwarsa, atau memiliki cakupan untuk aplikasi yang berbeda. Kunci yang tidak ada mengembalikan `403`; kunci yang salah, dicabut, atau kedaluwarsa mengembalikan `401`.",
            "content": {
              "application/json": {
                "examples": {
                  "Forbidden": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Batas laju terlampaui; lakukan back off dan coba lagi.",
            "content": {
              "application/json": {
                "examples": {
                  "Throttled": {
                    "value": {
                      "detail": "Request was throttled. Expected available in 30 seconds."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/webhook/destinations/{destination_uuid}/": {
      "get": {
        "summary": "Dapatkan tujuan webhook",
        "description": "Ambil satu tujuan webhook beserta rahasia penandatanganan `secret_shared_key`, statusnya (`health_status`, `failing_streak`, `failing_since`, `last_success_at`), dan `summary` pengiriman selama 30 hari terakhir. Pemanggil dengan kunci API selalu menerima rahasia secara lengkap; pengguna Konsol tanpa `read:webhooks` melihat string kosong.",
        "operationId": "get_webhook_destination",
        "x-didit-sdk": {
          "resource": "webhooks.destinations",
          "method": "retrieve",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Webhook"
        ],
        "parameters": [
          {
            "name": "destination_uuid",
            "in": "path",
            "required": true,
            "description": "UUID tujuan (`uuid` yang dikembalikan dari operasi create / list).",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "11111111-2222-3333-4444-555555555555"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/webhook/destinations/11111111-2222-3333-4444-555555555555/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.webhooks.destinations.retrieve(\n    \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.webhooks.destinations.retrieve(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Webhooks.Destinations.Retrieve(ctx, \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.webhooks().destinations().retrieve(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->webhooks->destinations->retrieve('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.webhooks.destinations.retrieve(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Webhooks.Destinations.RetrieveAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "Detail tujuan webhook.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "uuid": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "label": {
                      "type": "string"
                    },
                    "url": {
                      "type": "string",
                      "format": "uri"
                    },
                    "enabled": {
                      "type": "boolean"
                    },
                    "webhook_version": {
                      "type": "string",
                      "enum": [
                        "v1",
                        "v2",
                        "v3"
                      ]
                    },
                    "secret_shared_key": {
                      "type": "string",
                      "description": "Rahasia penandatanganan HMAC (token aman untuk URL 43 karakter). Selalu dikembalikan lengkap kepada pemanggil yang menggunakan kunci API; pengguna Console memerlukan `read:webhooks`, jika tidak akan berupa string kosong."
                    },
                    "secret_last4": {
                      "type": "string",
                      "description": "Empat karakter terakhir dari rahasia penandatanganan tujuan saat ini, sehingga Anda dapat membedakan rahasia. Tidak cukup untuk memverifikasi tanda tangan."
                    },
                    "previous_secret_expires_at": {
                      "type": "string",
                      "format": "date-time",
                      "nullable": true,
                      "description": "Ditetapkan selama 24 jam setelah rahasia penandatanganan tujuan dirotasi di Business Console. Hingga waktu ini, setiap pengiriman ke tujuan juga membawa `X-Signature-Previous`, `X-Signature-V2-Previous`, dan `X-Signature-Simple-Previous`, yang dibuat dengan rahasia yang diganti (lihat [Verifikasi tanda tangan](/id/integration/webhooks#verifikasi-tanda-tangan)). `null` jika tidak ada rotasi yang terjadi dalam 24 jam terakhir."
                    },
                    "subscribed_events": {
                      "$ref": "#/components/schemas/WebhookSubscribedEvents"
                    },
                    "created_by_email": {
                      "type": "string",
                      "nullable": true,
                      "description": "Email anggota Business Console yang membuat tujuan. `null` untuk tujuan yang dibuat dengan kunci API."
                    },
                    "created_by_name": {
                      "type": "string",
                      "nullable": true,
                      "description": "Nama anggota Business Console yang membuat tujuan. Bernilai `null` untuk tujuan yang dibuat dengan kunci API."
                    },
                    "created_at": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "updated_at": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "health_status": {
                      "type": "string",
                      "enum": [
                        "healthy",
                        "degraded",
                        "failing"
                      ],
                      "description": "Status pengiriman. `failing`: 3 event berturut-turut atau lebih gagal pada upaya pengiriman pertamanya sejak tujuan terakhir kali merespons dengan berhasil (lihat `failing_streak`). `degraded`: tidak gagal (failing), tetapi upaya pengiriman gagal dalam 24 jam terakhir dan tidak ada upaya berikutnya yang berhasil mengirimkan event tersebut; percobaan ulang atau pengiriman ulang yang berhasil menyelesaikannya akan menghapus status ini. `healthy`: tidak keduanya. Independen dari `enabled`. Upaya yang gagal adalah upaya yang direspons dengan HTTP 400 ke atas, atau tidak direspons sama sekali."
                    },
                    "failing_streak": {
                      "type": "integer",
                      "description": "Berapa banyak event berturut-turut yang gagal pada upaya pengiriman pertamanya sejak tujuan terakhir kali merespons dengan berhasil, dalam 30 hari terakhir. Coba lagi tidak dihitung, dan setiap upaya yang berhasil, termasuk coba lagi atau pengiriman ulang, mengakhiri rentetan tersebut. `0` jika tidak ada event yang gagal sejak keberhasilan terakhir."
                    },
                    "failing_since": {
                      "type": "string",
                      "format": "date-time",
                      "nullable": true,
                      "description": "Waktu ketika upaya gagal pertama dari `failing_streak` saat ini dilakukan. `null` jika `failing_streak` bernilai `0`."
                    },
                    "last_success_at": {
                      "type": "string",
                      "format": "date-time",
                      "nullable": true,
                      "description": "Waktu ketika tujuan terakhir kali merespons pengiriman dengan status HTTP di bawah 400, dalam 30 hari terakhir. `null` jika tidak merespons dalam rentang waktu tersebut."
                    },
                    "environment": {
                      "type": "string",
                      "enum": [
                        "live",
                        "sandbox"
                      ],
                      "description": "Lingkungan aplikasi yang memiliki tujuan tersebut."
                    },
                    "summary": {
                      "type": "object",
                      "description": "Metrik pengiriman selama `metrics_window_days` (30) hari terakhir. `last_delivery_at` adalah upaya paling baru, kapan pun upaya tersebut dilakukan.",
                      "properties": {
                        "total_deliveries": {
                          "type": "integer"
                        },
                        "failed_deliveries": {
                          "type": "integer"
                        },
                        "error_rate_percentage": {
                          "type": "integer"
                        },
                        "min_response_time_ms": {
                          "type": "integer",
                          "nullable": true
                        },
                        "avg_response_time_ms": {
                          "type": "integer",
                          "nullable": true
                        },
                        "max_response_time_ms": {
                          "type": "integer",
                          "nullable": true
                        },
                        "last_delivery_at": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true
                        },
                        "metrics_window_days": {
                          "type": "integer",
                          "description": "Panjang dalam hari dari jendela yang dicakup oleh metrik ringkasan lainnya. Selalu `30`."
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "Healthy destination": {
                    "value": {
                      "uuid": "11111111-2222-3333-4444-555555555555",
                      "label": "Production session webhooks",
                      "url": "https://yourapp.com/webhooks/didit",
                      "enabled": true,
                      "webhook_version": "v3",
                      "secret_shared_key": "tno2NTeRC1ZK3sBOYlBJDyEzBVENl3pQ1AcZyAW0xnQ",
                      "secret_last4": "0xnQ",
                      "previous_secret_expires_at": null,
                      "subscribed_events": [
                        "status.updated",
                        "data.updated"
                      ],
                      "created_by_email": null,
                      "created_by_name": null,
                      "created_at": "2026-01-04T08:00:00Z",
                      "updated_at": "2026-04-22T14:09:11Z",
                      "health_status": "healthy",
                      "failing_streak": 0,
                      "failing_since": null,
                      "last_success_at": "2026-05-17T09:21:18Z",
                      "environment": "live",
                      "summary": {
                        "total_deliveries": 12453,
                        "failed_deliveries": 14,
                        "error_rate_percentage": 0,
                        "min_response_time_ms": 41,
                        "avg_response_time_ms": 187,
                        "max_response_time_ms": 2103,
                        "last_delivery_at": "2026-05-17T09:21:18Z",
                        "metrics_window_days": 30
                      }
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Kunci API tidak ada, format salah, kedaluwarsa, atau memiliki cakupan untuk aplikasi yang berbeda. Kunci yang tidak ada mengembalikan `403`; kunci yang salah, dicabut, atau kedaluwarsa mengembalikan `401`.",
            "content": {
              "application/json": {
                "examples": {
                  "Forbidden": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Tidak ada tujuan dengan UUID ini, atau tujuan tersebut milik aplikasi lain, atau telah dihapus.",
            "content": {
              "application/json": {
                "examples": {
                  "Not found": {
                    "value": {
                      "detail": "Webhook destination not found."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Batas laju terlampaui; lakukan back off dan coba lagi.",
            "content": {
              "application/json": {
                "examples": {
                  "Throttled": {
                    "value": {
                      "detail": "Request was throttled. Expected available in 30 seconds."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      },
      "patch": {
        "summary": "Perbarui tujuan webhook",
        "description": "Perbarui tujuan webhook. **`subscribed_events` DIGANTI seluruhnya, bukan digabungkan**: ambil terlebih dahulu, tambahkan, kirim ulang. Rahasia tidak dirotasi. Nilai `uuid` di dalam body diabaikan: jalur menentukan tujuan.",
        "operationId": "update_webhook_destination",
        "x-didit-sdk": {
          "resource": "webhooks.destinations",
          "method": "update",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Webhook"
        ],
        "parameters": [
          {
            "name": "destination_uuid",
            "in": "path",
            "required": true,
            "description": "UUID tujuan yang akan diperbarui.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "11111111-2222-3333-4444-555555555555"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "label": {
                    "type": "string",
                    "description": "Nama baru yang dapat dibaca manusia."
                  },
                  "url": {
                    "type": "string",
                    "format": "uri",
                    "description": "URL target baru. Harus unik dalam aplikasi."
                  },
                  "enabled": {
                    "type": "boolean",
                    "description": "Atur ke `false` untuk menjeda pengiriman ke tujuan ini tanpa menghapusnya."
                  },
                  "webhook_version": {
                    "type": "string",
                    "enum": [
                      "v1",
                      "v2",
                      "v3"
                    ],
                    "description": "Versi skema payload baru untuk pengiriman di masa mendatang."
                  },
                  "subscribed_events": {
                    "$ref": "#/components/schemas/WebhookSubscribedEvents"
                  }
                }
              },
              "examples": {
                "Pause destination": {
                  "value": {
                    "enabled": false
                  }
                },
                "Add transaction events": {
                  "value": {
                    "subscribed_events": [
                      "status.updated",
                      "data.updated",
                      "transaction.created",
                      "transaction.status.updated"
                    ]
                  }
                },
                "Move target URL": {
                  "value": {
                    "label": "Production session webhooks v2",
                    "url": "https://api.yourapp.com/webhooks/didit/v2"
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X PATCH 'https://verification.didit.me/v3/webhook/destinations/11111111-2222-3333-4444-555555555555/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"subscribed_events\": [\n      \"status.updated\",\n      \"data.updated\",\n      \"transaction.created\"\n    ]\n  }'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.webhooks.destinations.update(\n    \"11111111-2222-3333-4444-555555555555\",\n    enabled=False,\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.webhooks.destinations.update(\"11111111-2222-3333-4444-555555555555\", {\n  enabled: false,\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Webhooks.Destinations.Update(ctx, \"11111111-2222-3333-4444-555555555555\", didit.WebhooksDestinationsUpdateParams{\n\tEnabled: didit.Bool(false),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.WebhooksDestinationsUpdateParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.webhooks().destinations().update(\"11111111-2222-3333-4444-555555555555\", WebhooksDestinationsUpdateParams.builder()\n        .enabled(false)\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->webhooks->destinations->update('11111111-2222-3333-4444-555555555555', [\n    'enabled' => false,\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.webhooks.destinations.update(\n  \"11111111-2222-3333-4444-555555555555\",\n  enabled: false\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Webhooks.Destinations.UpdateAsync(\"11111111-2222-3333-4444-555555555555\", new WebhooksDestinationsUpdateParams\n{\n    Enabled = false,\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "Tujuan webhook yang diperbarui. Isi memiliki format yang sama seperti `GET /v3/webhook/destinations/{destination_uuid}/`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "uuid": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "label": {
                      "type": "string"
                    },
                    "url": {
                      "type": "string",
                      "format": "uri"
                    },
                    "enabled": {
                      "type": "boolean"
                    },
                    "webhook_version": {
                      "type": "string",
                      "enum": [
                        "v1",
                        "v2",
                        "v3"
                      ]
                    },
                    "secret_shared_key": {
                      "type": "string"
                    },
                    "secret_last4": {
                      "type": "string",
                      "description": "Empat karakter terakhir dari rahasia penandatanganan tujuan saat ini, sehingga Anda dapat membedakan rahasia. Tidak cukup untuk memverifikasi tanda tangan."
                    },
                    "previous_secret_expires_at": {
                      "type": "string",
                      "format": "date-time",
                      "nullable": true,
                      "description": "Ditetapkan selama 24 jam setelah rahasia penandatanganan tujuan dirotasi di Business Console. Hingga waktu ini, setiap pengiriman ke tujuan juga membawa `X-Signature-Previous`, `X-Signature-V2-Previous`, dan `X-Signature-Simple-Previous`, yang dibuat dengan rahasia yang diganti (lihat [Verifikasi tanda tangan](/id/integration/webhooks#verifikasi-tanda-tangan)). `null` jika tidak ada rotasi yang terjadi dalam 24 jam terakhir."
                    },
                    "subscribed_events": {
                      "$ref": "#/components/schemas/WebhookSubscribedEvents"
                    },
                    "created_by_email": {
                      "type": "string",
                      "nullable": true,
                      "description": "Email anggota Business Console yang membuat tujuan. `null` untuk tujuan yang dibuat dengan kunci API."
                    },
                    "created_by_name": {
                      "type": "string",
                      "nullable": true,
                      "description": "Nama anggota Business Console yang membuat tujuan. Bernilai `null` untuk tujuan yang dibuat dengan kunci API."
                    },
                    "created_at": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "updated_at": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "health_status": {
                      "type": "string",
                      "enum": [
                        "healthy",
                        "degraded",
                        "failing"
                      ],
                      "description": "Status pengiriman. `failing`: 3 event berturut-turut atau lebih gagal pada upaya pengiriman pertamanya sejak tujuan terakhir kali merespons dengan berhasil (lihat `failing_streak`). `degraded`: tidak gagal (failing), tetapi upaya pengiriman gagal dalam 24 jam terakhir dan tidak ada upaya berikutnya yang berhasil mengirimkan event tersebut; percobaan ulang atau pengiriman ulang yang berhasil menyelesaikannya akan menghapus status ini. `healthy`: tidak keduanya. Independen dari `enabled`. Upaya yang gagal adalah upaya yang direspons dengan HTTP 400 ke atas, atau tidak direspons sama sekali."
                    },
                    "failing_streak": {
                      "type": "integer",
                      "description": "Berapa banyak event berturut-turut yang gagal pada upaya pengiriman pertamanya sejak tujuan terakhir kali merespons dengan berhasil, dalam 30 hari terakhir. Coba lagi tidak dihitung, dan setiap upaya yang berhasil, termasuk coba lagi atau pengiriman ulang, mengakhiri rentetan tersebut. `0` jika tidak ada event yang gagal sejak keberhasilan terakhir."
                    },
                    "failing_since": {
                      "type": "string",
                      "format": "date-time",
                      "nullable": true,
                      "description": "Waktu ketika upaya gagal pertama dari `failing_streak` saat ini dilakukan. `null` jika `failing_streak` bernilai `0`."
                    },
                    "last_success_at": {
                      "type": "string",
                      "format": "date-time",
                      "nullable": true,
                      "description": "Waktu ketika tujuan terakhir kali merespons pengiriman dengan status HTTP di bawah 400, dalam 30 hari terakhir. `null` jika tidak merespons dalam rentang waktu tersebut."
                    },
                    "environment": {
                      "type": "string",
                      "enum": [
                        "live",
                        "sandbox"
                      ],
                      "description": "Lingkungan aplikasi yang memiliki tujuan tersebut."
                    },
                    "summary": {
                      "type": "object",
                      "properties": {
                        "total_deliveries": {
                          "type": "integer"
                        },
                        "failed_deliveries": {
                          "type": "integer"
                        },
                        "error_rate_percentage": {
                          "type": "integer"
                        },
                        "min_response_time_ms": {
                          "type": "integer",
                          "nullable": true
                        },
                        "avg_response_time_ms": {
                          "type": "integer",
                          "nullable": true
                        },
                        "max_response_time_ms": {
                          "type": "integer",
                          "nullable": true
                        },
                        "last_delivery_at": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true
                        },
                        "metrics_window_days": {
                          "type": "integer",
                          "description": "Panjang dalam hari dari jendela yang dicakup oleh metrik ringkasan lainnya. Selalu `30`."
                        }
                      },
                      "description": "Metrik pengiriman selama `metrics_window_days` (30) hari terakhir. `last_delivery_at` adalah upaya paling baru, kapan pun upaya tersebut dilakukan."
                    }
                  }
                },
                "examples": {
                  "Paused": {
                    "value": {
                      "uuid": "11111111-2222-3333-4444-555555555555",
                      "label": "Production session webhooks",
                      "url": "https://yourapp.com/webhooks/didit",
                      "enabled": false,
                      "webhook_version": "v3",
                      "secret_shared_key": "tno2NTeRC1ZK3sBOYlBJDyEzBVENl3pQ1AcZyAW0xnQ",
                      "secret_last4": "0xnQ",
                      "previous_secret_expires_at": null,
                      "subscribed_events": [
                        "status.updated",
                        "data.updated"
                      ],
                      "created_by_email": null,
                      "created_by_name": null,
                      "created_at": "2026-01-04T08:00:00Z",
                      "updated_at": "2026-05-17T11:02:55Z",
                      "health_status": "healthy",
                      "failing_streak": 0,
                      "failing_since": null,
                      "last_success_at": "2026-05-17T09:21:18Z",
                      "environment": "live",
                      "summary": {
                        "total_deliveries": 12453,
                        "failed_deliveries": 14,
                        "error_rate_percentage": 0,
                        "min_response_time_ms": 41,
                        "avg_response_time_ms": 187,
                        "max_response_time_ms": 2103,
                        "last_delivery_at": "2026-05-17T09:21:18Z",
                        "metrics_window_days": 30
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validasi gagal (URL duplikat, daftar event kosong/tidak dikenal, isi permintaan salah format).",
            "content": {
              "application/json": {
                "examples": {
                  "Duplicate URL": {
                    "value": {
                      "url": [
                        "This webhook destination already exists for the application."
                      ]
                    }
                  },
                  "Empty events": {
                    "value": {
                      "subscribed_events": [
                        "At least one subscribed event is required."
                      ]
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Kunci API tidak ada, format salah, kedaluwarsa, atau memiliki cakupan untuk aplikasi yang berbeda. Kunci yang tidak ada mengembalikan `403`; kunci yang salah, dicabut, atau kedaluwarsa mengembalikan `401`.",
            "content": {
              "application/json": {
                "examples": {
                  "Forbidden": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Tujuan dengan UUID ini tidak ada (atau telah dihapus, atau milik aplikasi lain).",
            "content": {
              "application/json": {
                "examples": {
                  "Not found": {
                    "value": {
                      "detail": "Webhook destination not found."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Batas laju terlampaui; lakukan back off dan coba lagi.",
            "content": {
              "application/json": {
                "examples": {
                  "Throttled": {
                    "value": {
                      "detail": "Request was throttled. Expected available in 30 seconds."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      },
      "delete": {
        "summary": "Hapus tujuan webhook",
        "description": "Hapus tujuan webhook, rahasia penandatanganannya, dan seluruh log pengirimannya secara permanen. Tindakan ini tidak dapat dibatalkan. Tidak ada webhook baru yang dikirim ke URL tujuan; tujuan lain yang berlangganan event yang sama akan tetap menerimanya. Setelah itu, tujuan tidak lagi muncul di `GET /v3/webhook/destinations/`, dan setiap rute di bawah `/v3/webhook/destinations/{destination_uuid}/`, termasuk pengirimannya, detail pengiriman, serta pengiriman ulangnya, merespons dengan 404. `webhook_url` lama aplikasi diatur ke URL tujuan aktif tertua yang tersisa, atau dikosongkan jika tidak ada tujuan aktif yang tersisa. Memanggil DELETE lagi mengembalikan 404.",
        "operationId": "delete_webhook_destination",
        "x-didit-sdk": {
          "resource": "webhooks.destinations",
          "method": "delete",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Webhook"
        ],
        "parameters": [
          {
            "name": "destination_uuid",
            "in": "path",
            "required": true,
            "description": "UUID tujuan yang akan dihapus.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "11111111-2222-3333-4444-555555555555"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X DELETE 'https://verification.didit.me/v3/webhook/destinations/11111111-2222-3333-4444-555555555555/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nclient.webhooks.destinations.delete(\n    \"11111111-2222-3333-4444-555555555555\",\n)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nawait didit.webhooks.destinations.delete(\"11111111-2222-3333-4444-555555555555\");"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nif err := client.Webhooks.Destinations.Delete(ctx, \"11111111-2222-3333-4444-555555555555\"); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nclient.webhooks().destinations().delete(\"11111111-2222-3333-4444-555555555555\");"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$didit->webhooks->destinations->delete('11111111-2222-3333-4444-555555555555');"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.webhooks.destinations.delete(\"11111111-2222-3333-4444-555555555555\")"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nawait client.Webhooks.Destinations.DeleteAsync(\"11111111-2222-3333-4444-555555555555\");"
          }
        ],
        "responses": {
          "204": {
            "description": "Tujuan, rahasia penandatanganan, dan log pengiriman dihapus secara permanen. Tidak ada isi respons."
          },
          "403": {
            "description": "Kunci API tidak ada, format salah, kedaluwarsa, atau memiliki cakupan untuk aplikasi yang berbeda. Kunci yang tidak ada mengembalikan `403`; kunci yang salah, dicabut, atau kedaluwarsa mengembalikan `401`.",
            "content": {
              "application/json": {
                "examples": {
                  "Forbidden": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Tidak ada tujuan dengan UUID ini untuk aplikasi tersebut (sudah dihapus atau tidak pernah ada).",
            "content": {
              "application/json": {
                "examples": {
                  "Not found": {
                    "value": {
                      "detail": "Webhook destination not found."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Batas laju terlampaui; lakukan back off dan coba lagi.",
            "content": {
              "application/json": {
                "examples": {
                  "Throttled": {
                    "value": {
                      "detail": "Request was throttled. Expected available in 30 seconds."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/wallet-screening/": {
      "post": {
        "summary": "Skrining alamat dompet",
        "description": "Jalankan Skrining AML sesuai permintaan untuk satu dompet/alamat kripto tanpa membuat transaksi. Menentukan penyedia analitik blockchain yang dikonfigurasi untuk aplikasi Anda, melakukan skrining alamat secara sinkron, dan mengembalikan hasil risiko yang dinormalisasi. LIGHTNING hanya tersedia dengan koneksi BYOK Elliptic atau Chainalysis yang ditambahkan melalui Marketplace. Tidak ada yang ditulis ke tabel transaksi. Satu penggunaan pemantauan AML ditagih per skrining yang berhasil (aplikasi sandbox tidak ditagih).",
        "operationId": "screenWallet",
        "x-didit-sdk": {
          "resource": "wallet_screening",
          "method": "screen",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Transactions"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "wallet_address"
                ],
                "properties": {
                  "wallet_address": {
                    "type": "string",
                    "description": "Alamat kripto atau pengidentifikasi jaringan yang akan diskrining. Harus cocok dengan jaringan yang dipilih (misalnya alamat 40 karakter heksadesimal berawalan `0x` untuk rantai EVM). Alias: `address`.",
                    "example": "0x94f1b9b64e2932f6a2db338f616844400cd58e8a"
                  },
                  "blockchain": {
                    "type": "string",
                    "description": "Pengidentifikasi jaringan opsional. Jika diabaikan, jaringan dibaca dari format alamat: alamat `bc1`, `1`, dan `3` adalah Bitcoin (BTC), alamat `T` adalah Tron (TRX), dan kunci publik base58 adalah Solana (SOL). Alamat `0x` valid di setiap jaringan EVM, sehingga mengabaikan `blockchain` untuk alamat tersebut akan menghasilkan respons 422 dengan kandidat jaringan di `candidate_chains`. Skrining terkelola mendukung BTC, ETH, LTC, XRP, BCH, DOGE, TRX, SOL, MATIC, BNB, BASE (Base), OP (Optimism), ARB (Arbitrum One), AVAX (Avalanche C-Chain), ADA (Cardano), XLM (Stellar), dan HBAR (Hedera). USDT dan USDC adalah alias lama Ethereum, bukan pencarian multi-jaringan. Cakupan penyedia terhubung bervariasi. LIGHTNING memerlukan penyedia terhubung yang didukung. CELO (Celo), MODE (Mode), dan PLUME (Plume) diskrining melalui akun TRM Labs yang terhubung; skrining terkelola menghasilkan respons 400 untuk ketiganya. Alias: `currency`.",
                    "enum": [
                      "BTC",
                      "LIGHTNING",
                      "ETH",
                      "LTC",
                      "XRP",
                      "BCH",
                      "DOGE",
                      "TRX",
                      "SOL",
                      "MATIC",
                      "BNB",
                      "USDT",
                      "USDC",
                      "BASE",
                      "OP",
                      "ARB",
                      "AVAX",
                      "ADA",
                      "XLM",
                      "HBAR",
                      "CELO",
                      "MODE",
                      "PLUME"
                    ],
                    "example": "ETH"
                  },
                  "direction": {
                    "type": "string",
                    "description": "Opsional. Menentukan apakah alamat diskrining sebagai pihak lawan masuk/inbound (deposit) atau keluar/outbound (penarikan). Menerima `inbound`, `outbound`, `deposit`, atau `withdrawal`. Defaultnya adalah skrining pra-transfer netral jika dihilangkan. Nilai ini diteruskan ke penyedia hanya sebagai konteks; tidak mengubah `risk_score`, `severity`, atau rincian `source_of_funds`/`destination_of_funds` yang dikembalikan, yang keduanya selalu dikembalikan terlepas dari `direction`. Oleh karena itu, mengubah atau menghilangkan `direction` tidak memerlukan skrining ulang alamat.",
                    "enum": [
                      "inbound",
                      "outbound",
                      "deposit",
                      "withdrawal"
                    ]
                  }
                }
              },
              "example": {
                "wallet_address": "0x94f1b9b64e2932f6a2db338f616844400cd58e8a",
                "blockchain": "ETH"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://verification.didit.me/v3/wallet-screening/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"wallet_address\": \"0x94f1b9b64e2932f6a2db338f616844400cd58e8a\",\n    \"blockchain\": \"ETH\"\n  }'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.wallet_screening.screen(\n    wallet_address=\"0x94f1b9b64e2932f6a2db338f616844400cd58e8a\",\n    blockchain=\"ETH\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.walletScreening.screen({\n  wallet_address: \"0x94f1b9b64e2932f6a2db338f616844400cd58e8a\",\n  blockchain: \"ETH\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.WalletScreening.Screen(ctx, didit.WalletScreeningScreenParams{\n\tWalletAddress: \"0x94f1b9b64e2932f6a2db338f616844400cd58e8a\",\n\tBlockchain:    didit.Some(didit.WalletScreeningScreenParamsBlockchain(\"ETH\")),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.WalletScreeningScreenParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.walletScreening().screen(WalletScreeningScreenParams.builder()\n        .walletAddress(\"0x94f1b9b64e2932f6a2db338f616844400cd58e8a\")\n        .blockchain(WalletScreeningScreenParams.Blockchain.of(\"ETH\"))\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->walletScreening->screen([\n    'wallet_address' => '0x94f1b9b64e2932f6a2db338f616844400cd58e8a',\n    'blockchain' => 'ETH',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.wallet_screening.screen(\n  wallet_address: \"0x94f1b9b64e2932f6a2db338f616844400cd58e8a\",\n  blockchain: \"ETH\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.WalletScreening.ScreenAsync(new WalletScreeningScreenParams\n{\n    WalletAddress = \"0x94f1b9b64e2932f6a2db338f616844400cd58e8a\",\n    Blockchain = new WalletScreeningScreenParamsBlockchain(\"ETH\"),\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "Hasil skrining dompet yang dinormalisasi.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WalletScreeningResult"
                },
                "example": {
                  "provider": "merklescience",
                  "screening_type": "WALLET_SCREENING",
                  "risk_score": 95,
                  "severity": "CRITICAL",
                  "status": "SCREENED",
                  "summary": "Merkle Science risk: Critical (5/5). SANCTIONS HIT. Dominant risk: sanctioned. Driven by: the address is attributed to Sanctions / OFAC (Example Sanctions)",
                  "wallet_address": "0x94f1b9b64e2932f6a2db338f616844400cd58e8a",
                  "transaction_hash": null,
                  "blockchain": "ETH",
                  "block_timestamp": null,
                  "total_value_usd": null,
                  "fee_usd": null,
                  "sender_rows": [],
                  "receiver_rows": [],
                  "transaction_flows": [],
                  "transaction_flows_status": null,
                  "transaction_flows_error": null,
                  "source_of_funds": [
                    {
                      "category": "sanctioned",
                      "percentage": 100.0,
                      "amount_usd": 9813695.0,
                      "entity_name": "Example Sanctions",
                      "entity_type": "Sanctions",
                      "entity_subtype": "OFAC",
                      "hops": null,
                      "description": "Sanctions / OFAC",
                      "is_direct": true,
                      "exposure_direction": "incoming",
                      "exposure_type": "direct",
                      "provider_entity_id": "118885",
                      "provider_entity_type_id": "30",
                      "provider_entity_subtype_id": "125",
                      "country": "",
                      "raw_amount": null,
                      "raw_currency": null
                    }
                  ],
                  "destination_of_funds": [
                    {
                      "category": "defi",
                      "percentage": 84.824453,
                      "amount_usd": 7783414.38,
                      "entity_name": "Example DeFi 7",
                      "entity_type": "DeFi",
                      "entity_subtype": "Bridges",
                      "hops": null,
                      "description": "DeFi / Bridges",
                      "is_direct": false,
                      "exposure_direction": "outgoing",
                      "exposure_type": "indirect",
                      "provider_entity_id": "118459",
                      "provider_entity_type_id": "33",
                      "provider_entity_subtype_id": "143",
                      "country": "",
                      "raw_amount": null,
                      "raw_currency": null
                    },
                    {
                      "category": "defi",
                      "percentage": 15.175547,
                      "amount_usd": 1392494.37,
                      "entity_name": "Example DeFi 2",
                      "entity_type": "DeFi",
                      "entity_subtype": "Yield Aggregator",
                      "hops": null,
                      "description": "DeFi / Yield Aggregator",
                      "is_direct": false,
                      "exposure_direction": "outgoing",
                      "exposure_type": "indirect",
                      "provider_entity_id": "90192",
                      "provider_entity_type_id": "33",
                      "provider_entity_subtype_id": "142",
                      "country": "",
                      "raw_amount": null,
                      "raw_currency": null
                    }
                  ],
                  "counterparty_connections": [
                    {
                      "entity_name": "Example Sanctions",
                      "entity_type": "Sanctions",
                      "entity_subtype": "OFAC",
                      "risk_level": "critical",
                      "categories": [
                        "sanctioned"
                      ],
                      "received_usd": null,
                      "sent_usd": null,
                      "received_hops": null,
                      "sent_hops": null,
                      "percentage": 0.0,
                      "is_direct": true,
                      "country": null,
                      "provider_entity_id": null
                    },
                    {
                      "entity_name": "Example Sanctions",
                      "entity_type": "Sanctions",
                      "entity_subtype": "OFAC",
                      "risk_level": "critical",
                      "categories": [
                        "sanctioned"
                      ],
                      "received_usd": null,
                      "sent_usd": null,
                      "received_hops": null,
                      "sent_hops": null,
                      "percentage": 0.0,
                      "is_direct": true,
                      "country": null,
                      "provider_entity_id": null
                    }
                  ],
                  "network_nodes": [],
                  "network_edges": [],
                  "sanctions_hit": true,
                  "pep_counterparty": null,
                  "dominant_risk_category": "sanctioned",
                  "risk_factors": [
                    {
                      "source": "attribution",
                      "category": "sanctioned",
                      "label": "Sanctions / OFAC",
                      "entity_name": "Example Sanctions",
                      "direction": "attribution",
                      "exposure_type": "attribution",
                      "amount_usd": null,
                      "percentage": 0.0,
                      "is_high_risk": true,
                      "description": "the address is attributed to Sanctions / OFAC (Example Sanctions)"
                    },
                    {
                      "source": "exposure",
                      "category": "sanctioned",
                      "label": "Sanctions / OFAC",
                      "entity_name": "Example Sanctions",
                      "direction": "incoming",
                      "exposure_type": "direct",
                      "amount_usd": 9813695.0,
                      "percentage": 51.679304,
                      "is_high_risk": true,
                      "description": "51.6793% direct incoming exposure to Sanctions / OFAC (Example Sanctions)"
                    },
                    {
                      "source": "exposure",
                      "category": "defi",
                      "label": "DeFi / Bridges",
                      "entity_name": "Example DeFi 7",
                      "direction": "outgoing",
                      "exposure_type": "indirect",
                      "amount_usd": 7783414.38,
                      "percentage": 40.987766,
                      "is_high_risk": false,
                      "description": "40.9878% indirect outgoing exposure to DeFi / Bridges (Example DeFi 7)"
                    },
                    {
                      "source": "exposure",
                      "category": "defi",
                      "label": "DeFi / Yield Aggregator",
                      "entity_name": "Example DeFi 2",
                      "direction": "outgoing",
                      "exposure_type": "indirect",
                      "amount_usd": 1392494.37,
                      "percentage": 7.33293,
                      "is_high_risk": false,
                      "description": "7.33293% indirect outgoing exposure to DeFi / Yield Aggregator (Example DeFi 2)"
                    }
                  ],
                  "raw_response": {
                    "...": "provider-specific details"
                  },
                  "report_signature": "<hmac-sha256 over the result, scoped to your application>"
                }
              }
            }
          },
          "400": {
            "description": "Kesalahan validasi — alamat dompet salah format, `wallet_address` tidak ada, `blockchain` tidak didukung, `blockchain` dihilangkan untuk alamat yang formatnya tidak menyebutkan jaringan, atau LIGHTNING tanpa koneksi Marketplace BYOK Elliptic atau Chainalysis."
          },
          "401": {
            "description": "`x-api-key` tidak ada atau tidak valid."
          },
          "409": {
            "description": "Tidak ada penyedia AML yang dikonfigurasi untuk aplikasi, atau penyedia yang dikonfigurasi belum mendukung skrining dompet. Konfigurasikan pemantauan transaksi terlebih dahulu."
          },
          "422": {
            "description": "`blockchain` dihilangkan untuk alamat `0x`, yang digunakan bersama oleh setiap jaringan EVM. Tidak ada yang diskrining atau ditagih; kirim ulang dengan `blockchain` diatur ke salah satu dari `candidate_chains`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "blockchain": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "example": [
                        "A 0x address is valid on every EVM chain. Send blockchain as one of: ETH, BNB, MATIC, BASE, ARB, OP, CELO, MODE, PLUME."
                      ]
                    },
                    "candidate_chains": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "example": [
                        "ETH",
                        "BNB",
                        "MATIC",
                        "BASE",
                        "ARB",
                        "OP",
                        "CELO",
                        "MODE",
                        "PLUME"
                      ]
                    }
                  }
                }
              }
            }
          },
          "502": {
            "description": "Penyedia AML tidak dapat menyelesaikan skrining. Coba lagi nanti."
          }
        }
      }
    },
    "/v3/wallet-screening/pdf/": {
      "post": {
        "summary": "Render hasil Skrining Dompet sebagai PDF",
        "description": "Pelengkap stateless untuk `POST /v3/wallet-screening/`: kirim ulang body JSON persis seperti yang dikembalikan endpoint tersebut — termasuk `report_signature` yang ditambahkan — dan dapatkan kembali PDF bermerek Didit dengan hasil yang sama. Tidak ada penyedia yang dipanggil dan tidak ada yang ditagihkan atau disimpan; ini hanya merender ulang hasil yang telah dibuat oleh Didit. Tanda tangan mengikat PDF ke hasil yang belum dimodifikasi: mengedit `risk_score`, `severity`, `sanctions_hit`, atau kolom lain yang ditandatangani sebelum mengirim ulang akan gagal dengan `400`.",
        "operationId": "screenWalletPdf",
        "x-didit-sdk": {
          "resource": "wallet_screening",
          "method": "screen_pdf",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Transactions"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "description": "Objek JSON yang tidak dimodifikasi yang dikembalikan oleh `POST /v3/wallet-screening/`, termasuk `report_signature`.",
          "content": {
            "application/json": {
              "schema": {
                "allOf": [
                  {
                    "$ref": "#/components/schemas/WalletScreeningResult"
                  }
                ],
                "required": [
                  "report_signature"
                ],
                "description": "Struktur yang sama dengan respons `POST /v3/wallet-screening/` — teruskan isi respons tersebut kembali apa adanya, termasuk `report_signature`."
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "# $RESULT is the saved JSON body from POST /v3/wallet-screening/\ncurl -X POST 'https://verification.didit.me/v3/wallet-screening/pdf/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d \"$RESULT\" \\\n  -o wallet_screening_report.pdf"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\ncontent = client.wallet_screening.screen_pdf(\n    provider=\"your-provider\",\n    screening_type=\"WALLET_SCREENING\",\n    risk_score=1,\n    severity=\"UNKNOWN\",\n    status=\"SCREENED\",\n    summary=\"your-summary\",\n    wallet_address=\"your-wallet-address\",\n    blockchain=\"your-blockchain\",\n    source_of_funds=[{}],\n    destination_of_funds=[{}],\n    counterparty_connections=[{}],\n    sanctions_hit=True,\n    dominant_risk_category=\"your-dominant-risk-category\",\n    report_signature=\"your-report-signature\",\n)\nwith open(\"download.pdf\", \"wb\") as file:\n    file.write(content)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import { writeFile } from \"node:fs/promises\";\nimport Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst content = await didit.walletScreening.screenPdf({\n  provider: \"your-provider\",\n  screening_type: \"WALLET_SCREENING\",\n  risk_score: 1,\n  severity: \"UNKNOWN\",\n  status: \"SCREENED\",\n  summary: \"your-summary\",\n  wallet_address: \"your-wallet-address\",\n  blockchain: \"your-blockchain\",\n  source_of_funds: [{}],\n  destination_of_funds: [{}],\n  counterparty_connections: [{}],\n  sanctions_hit: true,\n  dominant_risk_category: \"your-dominant-risk-category\",\n  report_signature: \"your-report-signature\",\n});\nawait writeFile(\"download.pdf\", Buffer.from(await content.arrayBuffer()));"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresp, err := client.WalletScreening.ScreenPDF(ctx, didit.WalletScreeningResultParam{\n\tProvider:                \"your-provider\",\n\tScreeningType:           \"WALLET_SCREENING\",\n\tRiskScore:               1,\n\tSeverity:                \"UNKNOWN\",\n\tStatus:                  \"SCREENED\",\n\tSummary:                 \"your-summary\",\n\tWalletAddress:           \"your-wallet-address\",\n\tBlockchain:              \"your-blockchain\",\n\tSourceOfFunds:           []didit.WalletScreeningResultParamSourceOfFunds{{}},\n\tDestinationOfFunds:      []didit.WalletScreeningResultParamDestinationOfFunds{{}},\n\tCounterpartyConnections: []didit.WalletScreeningResultParamCounterpartyConnections{{}},\n\tSanctionsHit:            true,\n\tDominantRiskCategory:    didit.String(\"your-dominant-risk-category\"),\n\tReportSignature:         \"your-report-signature\",\n})\nif err != nil {\n\tlog.Fatal(err)\n}\ndefer resp.Body.Close()\nfile, err := os.Create(\"download.pdf\")\nif err != nil {\n\tlog.Fatal(err)\n}\ndefer file.Close()\nif _, err := io.Copy(file, resp.Body); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.nio.file.Path;\nimport java.util.List;\nimport me.didit.Didit;\nimport me.didit.types.WalletScreeningResult;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nclient.walletScreening().screenPdf(WalletScreeningResult.builder()\n        .provider(\"your-provider\")\n        .screeningType(WalletScreeningResult.ScreeningType.of(\"WALLET_SCREENING\"))\n        .riskScore(1L)\n        .severity(WalletScreeningResult.Severity.of(\"UNKNOWN\"))\n        .status(WalletScreeningResult.Status.of(\"SCREENED\"))\n        .summary(\"your-summary\")\n        .walletAddress(\"your-wallet-address\")\n        .blockchain(\"your-blockchain\")\n        .sourceOfFunds(List.of(WalletScreeningResult.SourceOfFunds.builder()\n                .build()))\n        .destinationOfFunds(List.of(WalletScreeningResult.DestinationOfFunds.builder()\n                .build()))\n        .counterpartyConnections(List.of(WalletScreeningResult.CounterpartyConnections.builder()\n                .build()))\n        .sanctionsHit(true)\n        .dominantRiskCategory(\"your-dominant-risk-category\")\n        .reportSignature(\"your-report-signature\")\n        .build())\n        .writeTo(Path.of(\"download.pdf\"));"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$content = $didit->walletScreening->screenPdf([\n    'provider' => 'your-provider',\n    'screening_type' => 'WALLET_SCREENING',\n    'risk_score' => 1,\n    'severity' => 'UNKNOWN',\n    'status' => 'SCREENED',\n    'summary' => 'your-summary',\n    'wallet_address' => 'your-wallet-address',\n    'blockchain' => 'your-blockchain',\n    'source_of_funds' => [[]],\n    'destination_of_funds' => [[]],\n    'counterparty_connections' => [[]],\n    'sanctions_hit' => true,\n    'dominant_risk_category' => 'your-dominant-risk-category',\n    'report_signature' => 'your-report-signature',\n]);\n$content->saveTo('download.pdf');"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ncontent = didit.wallet_screening.screen_pdf(\n  provider: \"your-provider\",\n  screening_type: \"WALLET_SCREENING\",\n  risk_score: 1,\n  severity: \"UNKNOWN\",\n  status: \"SCREENED\",\n  summary: \"your-summary\",\n  wallet_address: \"your-wallet-address\",\n  blockchain: \"your-blockchain\",\n  source_of_funds: [{}],\n  destination_of_funds: [{}],\n  counterparty_connections: [{}],\n  sanctions_hit: true,\n  dominant_risk_category: \"your-dominant-risk-category\",\n  report_signature: \"your-report-signature\"\n)\nFile.binwrite(\"download.pdf\", content)"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar content = await client.WalletScreening.ScreenPdfAsync(new WalletScreeningResult\n{\n    Provider = \"your-provider\",\n    ScreeningType = \"WALLET_SCREENING\",\n    RiskScore = 1,\n    Severity = \"UNKNOWN\",\n    Status = \"SCREENED\",\n    Summary = \"your-summary\",\n    WalletAddress = \"your-wallet-address\",\n    Blockchain = \"your-blockchain\",\n    SourceOfFunds = new WalletScreeningResultSourceOfFunds[] { new() },\n    DestinationOfFunds = new WalletScreeningResultDestinationOfFunds[] { new() },\n    CounterpartyConnections = new WalletScreeningResultCounterpartyConnections[] { new() },\n    SanctionsHit = true,\n    DominantRiskCategory = \"your-dominant-risk-category\",\n    ReportSignature = \"your-report-signature\",\n});\nawait content.SaveToAsync(\"download.pdf\");"
          }
        ],
        "responses": {
          "200": {
            "description": "Dokumen PDF hasil render, dikembalikan langsung sebagai biner `application/pdf` — tidak ada pembungkus JSON.",
            "headers": {
              "Content-Disposition": {
                "description": "`attachment; filename=wallet_screening_{address}.pdf`, diturunkan dari `wallet_address` (atau `transaction_hash`) dalam hasil yang diposting ulang.",
                "schema": {
                  "type": "string",
                  "example": "attachment; filename=wallet_screening_0x28c6c06298d514db0899.pdf"
                }
              }
            },
            "content": {
              "application/pdf": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "400": {
            "description": "Isi body bukan berupa objek JSON yang cocok dengan bentuk hasil Skrining Dompet, atau `report_signature` tidak ada atau tidak cocok dengan kolom yang dikirim ulang (diedit atau dipotong sebelum dikirim ulang).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "examples": {
                  "Not an object": {
                    "value": {
                      "non_field_errors": [
                        "Expected a JSON object matching a wallet-screening result."
                      ]
                    }
                  },
                  "Missing or invalid signature": {
                    "value": {
                      "report_signature": [
                        "This wallet-screening result is missing or fails its report signature - repost the exact JSON returned by the wallet-screening endpoint, unmodified."
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "`x-api-key` tidak ada atau tidak valid."
          }
        }
      }
    },
    "/v3/transactions/": {
      "get": {
        "summary": "Daftar transaksi",
        "description": "Daftar transaksi yang dipantau secara berpaginasi, terbaru terlebih dahulu (`txn_date` desc). `count` dibatasi hingga 100; gunakan `total_transactions` untuk jumlah baris sebenarnya. Endpoint ini tidak mendukung pemfilteran atau parameter pencarian.",
        "operationId": "listTransactions",
        "x-didit-sdk": {
          "resource": "transactions",
          "method": "list",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Transactions"
        ],
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 50,
              "minimum": 1,
              "maximum": 1000000
            },
            "description": "Ukuran halaman. Nilai default-nya 50 jika dihilangkan. Tidak ada batasan maksimum yang diterapkan, tetapi jaga ukuran halaman tetap kecil demi latensi."
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 0,
              "minimum": 0,
              "maximum": 1000000
            },
            "description": "Offset berbasis nol dari rekaman pertama yang dikembalikan. Sebaiknya ikuti URL `next` dari halaman sebelumnya."
          },
          {
            "name": "travel_rule_status",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Hanya mengembalikan transaksi yang transfer Travel Rule-nya berada dalam status persis ini (misalnya `ON_HOLD` atau `AWAITING_COUNTERPARTY`). `count` mengikuti filter ini; `total_transactions` tetap menghitung setiap transaksi di aplikasi."
          },
          {
            "name": "assignee",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Dipisahkan koma; transaksi cocok jika memenuhi nilai apa pun. `unassigned` berarti belum dipegang siapa pun, `rules` berarti diputuskan oleh aturan sendiri tanpa peninjau, dan email anggota cocok dengan peninjau yang ditugaskan padanya. `me` adalah peninjau Konsol yang sedang masuk, sehingga kunci API yang mengirimkan `me` akan menerima `400`."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/transactions/?limit=50' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nfor item in client.transactions.list():\n    print(item)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nfor await (const item of didit.transactions.list()) {\n  console.log(item);\n}"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\niter := client.Transactions.ListAutoPaging(ctx, didit.TransactionsListParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nfor (var item : client.transactions().list()) {\n    System.out.println(item);\n}"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\nforeach ($didit->transactions->list() as $item) {\n    print_r($item->toArray());\n}"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.transactions.list.auto_paging_each do |item|\n  puts item.to_h\nend"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.Transactions.ListAsync())\n{\n    Console.WriteLine(JsonSerializer.Serialize(item));\n}"
          }
        ],
        "responses": {
          "200": {
            "description": "Daftar ringkasan transaksi berpaginasi, terbaru terlebih dahulu.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "count": {
                      "type": "integer",
                      "description": "Jumlah transaksi yang cocok yang dibatasi (akurat hingga 100, dibatasi setelahnya). Gunakan `total_transactions` untuk jumlah sebenarnya saat melakukan paginasi."
                    },
                    "next": {
                      "type": "string",
                      "nullable": true,
                      "description": "URL absolut halaman berikutnya, atau `null` di halaman terakhir."
                    },
                    "previous": {
                      "type": "string",
                      "nullable": true,
                      "description": "URL absolut halaman sebelumnya, atau `null` di halaman pertama."
                    },
                    "total_transactions": {
                      "type": "integer",
                      "description": "Jumlah total persis transaksi (yang belum dihapus) untuk aplikasi. Tersedia dalam respons berpaginasi."
                    },
                    "results": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "uuid": {
                            "type": "string",
                            "format": "uuid",
                            "description": "Pengidentifikasi transaksi Didit yang stabil. Gunakan sebagai `{transaction_id}` dalam panggilan detail/catatan/terkait."
                          },
                          "transaction_number": {
                            "type": "integer",
                            "description": "Nomor transaksi berurutan dalam cakupan aplikasi yang ditampilkan di Konsol (misalnya `4123`)."
                          },
                          "txn_id": {
                            "type": "string",
                            "description": "Pengenal yang diberikan pelanggan dari panggilan pembuatan (maks 128 karakter). Unik per aplikasi."
                          },
                          "transaction_type": {
                            "type": "string",
                            "description": "Kategori tingkat atas sebagaimana disimpan: `finance`, `kyc`, `travelRule`, `userPlatformEvent`, `gamblingBet`, `gamblingLimitChange`, `gamblingBonusChange`, `auditTrailEvent`. Perhatikan bahwa nilai multi-kata dikembalikan dalam camelCase bahkan ketika dikirimkan dalam snake_case."
                          },
                          "action_type": {
                            "type": "string",
                            "description": "Subtipe dalam kategori tersebut (misalnya `deposit`, `withdrawal`, `transfer`)."
                          },
                          "status": {
                            "type": "string",
                            "enum": [
                              "APPROVED",
                              "IN_REVIEW",
                              "DECLINED",
                              "AWAITING_USER"
                            ],
                            "description": "Keputusan pemantauan saat ini."
                          },
                          "direction": {
                            "type": "string",
                            "enum": [
                              "INBOUND",
                              "OUTBOUND"
                            ],
                            "description": "Arah relatif terhadap subjek. Disimpan dalam huruf besar terlepas dari format huruf yang dikirim."
                          },
                          "amount": {
                            "type": "string",
                            "description": "Jumlah transaksi sebagai string desimal dengan nol di akhir yang dihilangkan (misalnya `\"1500\"`, `\"0.5\"`, `\"0.123456789012345678\"`). Hingga 18 tempat desimal."
                          },
                          "currency": {
                            "type": "string",
                            "description": "Kode mata uang untuk `amount`. Kode alfabet ISO 4217 apa pun diterima (misalnya `EUR`, `USD`, `NGN`), begitu pula simbol aset kripto (misalnya `BTC`). Sebaiknya gunakan kode yang saat ini beredar. Tidak semua kode yang diterima memiliki nilai tukar: jika tidak ada nilai tukar yang tersedia untuk kode tersebut (misalnya unit akuntansi ISO `XSU`, atau simbol kripto yang harganya tidak ditetapkan oleh Didit), konversi otomatis gagal dan `preferred_currency_amount` dikembalikan sebagai null kecuali permintaan menyertakan `amount_in_default_currency` yang telah dikonversi sebelumnya."
                          },
                          "preferred_currency_amount": {
                            "type": "string",
                            "nullable": true,
                            "description": "`amount` dikonversi ke mata uang pilihan aplikasi, jika tersedia."
                          },
                          "preferred_currency_code": {
                            "type": "string",
                            "nullable": true,
                            "description": "Kode mata uang pilihan yang digunakan untuk `preferred_currency_amount` - mata uang dasar aplikasi, kode ISO 4217 apa pun yang saat ini beredar. Kode tanpa nilai tukar yang tersedia membuat `preferred_currency_amount` bernilai null kecuali permintaan menyertakan `amount_in_default_currency` yang telah dikonversi sebelumnya."
                          },
                          "payment_details": {
                            "type": "string",
                            "nullable": true,
                            "description": "Referensi atau memo pembayaran teks bebas dari pengiriman."
                          },
                          "score": {
                            "type": "integer",
                            "description": "Skor risiko (biasanya 0–100). Lebih tinggi = lebih berisiko."
                          },
                          "severity": {
                            "type": "string",
                            "nullable": true,
                            "enum": [
                              "UNKNOWN",
                              "LOW",
                              "MEDIUM",
                              "HIGH",
                              "CRITICAL"
                            ],
                            "description": "Tingkat keparahan risiko kategoris yang ditetapkan oleh aturan/penyedia (`UNKNOWN`, `LOW`, `MEDIUM`, `HIGH`, `CRITICAL`). Bernilai `null` hingga ada yang menetapkannya."
                          },
                          "subject_name": {
                            "type": "string",
                            "nullable": true,
                            "description": "Nama lengkap pihak `APPLICANT`."
                          },
                          "subject_vendor_data": {
                            "type": "string",
                            "nullable": true,
                            "description": "Pengenal pengguna/bisnis internal Anda untuk pemohon."
                          },
                          "subject_country": {
                            "type": "string",
                            "nullable": true,
                            "description": "Kode negara pemohon, dari `address.country` yang dikirimkan (biasanya ISO 3166-1 alpha-3)."
                          },
                          "counterparty_name": {
                            "type": "string",
                            "nullable": true,
                            "description": "Nama lengkap pihak `COUNTERPARTY`, jika ada."
                          },
                          "counterparty_vendor_data": {
                            "type": "string",
                            "nullable": true,
                            "description": "Pengenal internal Anda untuk pihak lawan."
                          },
                          "counterparty_country": {
                            "type": "string",
                            "nullable": true,
                            "description": "Kode negara pihak lawan, dari `address.country` yang dikirimkan."
                          },
                          "tags": {
                            "type": "array",
                            "description": "Tag yang dilampirkan ke transaksi (secara manual atau berdasarkan aturan).",
                            "items": {
                              "type": "object",
                              "properties": {
                                "uuid": {
                                  "type": "string",
                                  "format": "uuid"
                                },
                                "name": {
                                  "type": "string"
                                },
                                "color": {
                                  "type": "string"
                                },
                                "description": {
                                  "type": "string",
                                  "nullable": true
                                },
                                "source": {
                                  "type": "string",
                                  "enum": [
                                    "didit",
                                    "custom"
                                  ],
                                  "description": "Apakah tag tersebut merupakan preset Didit atau tag kustom."
                                }
                              }
                            }
                          },
                          "txn_date": {
                            "type": "string",
                            "format": "date-time",
                            "description": "Kapan transaksi terjadi (dari `transaction_at` pada saat pembuatan)."
                          },
                          "created_at": {
                            "type": "string",
                            "format": "date-time",
                            "description": "Waktu ketika Didit mencatat pengiriman tersebut."
                          },
                          "decision_reason_code": {
                            "type": "string",
                            "nullable": true,
                            "description": "Alasan yang dapat dibaca mesin untuk `status` saat ini (misalnya `WALLET_HIGH_RISK`)."
                          },
                          "decision_reason_label": {
                            "type": "string",
                            "nullable": true,
                            "description": "Label yang mudah dibaca manusia untuk `decision_reason_code`."
                          },
                          "assigned_to_name": {
                            "type": "string",
                            "nullable": true,
                            "description": "Nama tampilan peninjau Console yang ditugaskan untuk transaksi ini."
                          },
                          "travel_rule_status": {
                            "type": "string",
                            "nullable": true,
                            "description": "Status transfer Travel Rule milik transaksi (misalnya `COMPLETED`), atau `null` jika tidak ada."
                          },
                          "travel_rule": {
                            "nullable": true,
                            "allOf": [
                              {
                                "$ref": "#/components/schemas/TransactionTravelRule"
                              }
                            ],
                            "description": "Transfer Travel Rule milik transaksi tersebut, blok yang sama dengan `travel_rule` pada `GET /v3/transactions/{transaction_id}/`, atau `null` jika transaksi tidak memilikinya."
                          }
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "Single transaction": {
                    "value": {
                      "count": 1,
                      "next": null,
                      "previous": null,
                      "total_transactions": 1,
                      "results": [
                        {
                          "uuid": "abcdef12-3456-4890-abcd-ef1234567890",
                          "transaction_number": 4123,
                          "txn_id": "your-txn-2026-05-17-001",
                          "transaction_type": "finance",
                          "action_type": "withdrawal",
                          "status": "IN_REVIEW",
                          "direction": "OUTBOUND",
                          "amount": "1500",
                          "currency": "EUR",
                          "preferred_currency_amount": "1620.45",
                          "preferred_currency_code": "USD",
                          "payment_details": "Withdrawal to crypto wallet",
                          "txn_date": "2026-05-17T08:42:00Z",
                          "created_at": "2026-05-17T08:42:11Z",
                          "score": 78,
                          "severity": "HIGH",
                          "decision_reason_code": "WALLET_HIGH_RISK",
                          "decision_reason_label": "Destination wallet flagged as high risk",
                          "tags": [
                            {
                              "uuid": "9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d",
                              "name": "Manual review",
                              "color": "#F59E0B",
                              "description": null,
                              "source": "custom"
                            }
                          ],
                          "subject_name": "Maria Garcia",
                          "subject_vendor_data": "user-12345",
                          "counterparty_name": null,
                          "counterparty_vendor_data": null,
                          "counterparty_country": null,
                          "subject_country": null,
                          "assigned_to_name": "Alex Reviewer",
                          "travel_rule_status": null,
                          "travel_rule": null
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Kunci API tidak ada, tidak valid, atau dicabut, atau kunci tersebut tidak dapat menampilkan daftar transaksi untuk aplikasi ini. Kunci yang tidak ada mengembalikan `403`; kunci yang salah, dicabut, atau kedaluwarsa mengembalikan `401`.",
            "content": {
              "application/json": {
                "examples": {
                  "Forbidden": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Batas laju terlampaui; kurangi laju permintaan dan coba lagi setelah interval yang ditunjukkan dalam `Retry-After`.",
            "content": {
              "application/json": {
                "examples": {
                  "Throttled": {
                    "value": {
                      "detail": "Request was throttled. Expected available in 30 seconds."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      },
      "post": {
        "summary": "Buat transaksi",
        "description": "Kirim transaksi untuk pemantauan AML/risiko sinkron. Transaksi dibuat dengan status `APPROVED`, lalu aturan Anda (dan skrining kripto, jika berlaku) dijalankan secara inline dan dapat mengubah `status` yang dikembalikan menjadi `IN_REVIEW` atau `DECLINED`. **`transaction_id` adalah kunci idempotensi Anda** (maks 128 karakter, unik per aplikasi); menggunakan kembali ID ini akan mengembalikan 400. Webhook `transaction.created` dikirim saat berhasil untuk aplikasi produksi. Aplikasi sandbox tidak ditagih dan tidak memancarkan webhook `transaction.created` atau `transaction.status.updated`. Pertukaran Travel Rule sandbox memancarkan webhook `travel_rule.status.updated` dengan `environment: sandbox`. Transfer Travel Rule disimpan dan dikembalikan sebelum pihak lawan dihubungi: `travel_rule.status` kembali dengan `AWAITING_COUNTERPARTY` (atau `NOT_APPLICABLE` jika di bawah ambang batas Anda, `UNCONFIRMED_OWNERSHIP` untuk dompet swakelola yang dideklarasikan, `COMPLETED` jika dompet lain tersebut adalah dompet terverifikasi milik Anda sendiri) dan `travel_rule.protocol` bernilai null. Didit kemudian memilih jalur dan mengirim pertukaran tersebut, dan setiap perubahan status transfer berikutnya, termasuk `COUNTERPARTY_VASP_NOT_FOUND` jika tidak ada jalur yang dapat menjangkau pihak lawan, akan diterima sebagai webhook `travel_rule.status.updated`. Aturan Anda akan dijalankan kembali saat jalur atau status berubah.",
        "operationId": "createTransaction",
        "tags": [
          "Transactions"
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://verification.didit.me/v3/transactions/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"transaction_id\": \"your-txn-2026-05-17-001\",\n    \"transaction_category\": \"finance\",\n    \"transaction_details\": {\n      \"direction\": \"outbound\",\n      \"amount\": 1500,\n      \"currency\": \"EUR\",\n      \"action_type\": \"withdrawal\"\n    },\n    \"subject\": {\n      \"entity_type\": \"individual\",\n      \"vendor_data\": \"user-12345\",\n      \"full_name\": \"Maria Garcia\"\n    }\n  }'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.transactions.create(\n    transaction_id=\"your-txn-2026-05-17-001\",\n    transaction_category=\"finance\",\n    transaction_details={\n        \"direction\": \"outbound\",\n        \"amount\": 1500.0,\n        \"currency\": \"EUR\",\n        \"action_type\": \"withdrawal\",\n    },\n    subject={\n        \"entity_type\": \"individual\",\n        \"vendor_data\": \"user-12345\",\n        \"full_name\": \"Maria Garcia\",\n    },\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.transactions.create({\n  transaction_id: \"your-txn-2026-05-17-001\",\n  transaction_category: \"finance\",\n  transaction_details: {\n    direction: \"outbound\",\n    amount: 1500.0,\n    currency: \"EUR\",\n    action_type: \"withdrawal\",\n  },\n  subject: {\n    entity_type: \"individual\",\n    vendor_data: \"user-12345\",\n    full_name: \"Maria Garcia\",\n  },\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Transactions.Create(ctx, didit.TransactionsCreateParams{\n\tTransactionID:       \"your-txn-2026-05-17-001\",\n\tTransactionCategory: \"finance\",\n\tTransactionDetails: didit.TransactionsCreateParamsTransactionDetails{\n\t\tDirection:  \"outbound\",\n\t\tAmount:     1500.0,\n\t\tCurrency:   \"EUR\",\n\t\tActionType: didit.String(\"withdrawal\"),\n\t},\n\tSubject: didit.TransactionsCreateParamsSubject{\n\t\tEntityType: didit.String(\"individual\"),\n\t\tVendorData: \"user-12345\",\n\t\tFullName:   \"Maria Garcia\",\n\t},\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.TransactionsCreateParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.transactions().create(TransactionsCreateParams.builder()\n        .transactionId(\"your-txn-2026-05-17-001\")\n        .transactionCategory(TransactionsCreateParams.TransactionCategory.of(\"finance\"))\n        .transactionDetails(TransactionsCreateParams.TransactionDetails.builder()\n                .direction(TransactionsCreateParams.TransactionDetails.Direction.of(\"outbound\"))\n                .amount(1500.0)\n                .currency(\"EUR\")\n                .actionType(\"withdrawal\")\n                .build())\n        .subject(TransactionsCreateParams.Subject.builder()\n                .entityType(\"individual\")\n                .vendorData(\"user-12345\")\n                .fullName(\"Maria Garcia\")\n                .build())\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->transactions->create([\n    'transaction_id' => 'your-txn-2026-05-17-001',\n    'transaction_category' => 'finance',\n    'transaction_details' => [\n        'direction' => 'outbound',\n        'amount' => 1500.0,\n        'currency' => 'EUR',\n        'action_type' => 'withdrawal',\n    ],\n    'subject' => [\n        'entity_type' => 'individual',\n        'vendor_data' => 'user-12345',\n        'full_name' => 'Maria Garcia',\n    ],\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.transactions.create(\n  transaction_id: \"your-txn-2026-05-17-001\",\n  transaction_category: \"finance\",\n  transaction_details: {\n    direction: \"outbound\",\n    amount: 1500.0,\n    currency: \"EUR\",\n    action_type: \"withdrawal\",\n  },\n  subject: {\n    entity_type: \"individual\",\n    vendor_data: \"user-12345\",\n    full_name: \"Maria Garcia\",\n  }\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Transactions.CreateAsync(new TransactionsCreateParams\n{\n    TransactionId = \"your-txn-2026-05-17-001\",\n    TransactionCategory = \"finance\",\n    TransactionDetails = new()\n    {\n        Direction = \"outbound\",\n        Amount = 1500.0,\n        Currency = \"EUR\",\n        ActionType = \"withdrawal\",\n    },\n    Subject = new()\n    {\n        EntityType = \"individual\",\n        VendorData = \"user-12345\",\n        FullName = \"Maria Garcia\",\n    },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "transaction_id": {
                    "type": "string",
                    "description": "Pengidentifikasi unik Anda untuk transaksi ini (maks 128 karakter).",
                    "example": "your-txn-2026-05-17-001"
                  },
                  "transaction_at": {
                    "type": "string",
                    "format": "date-time",
                    "description": "Kapan transaksi terjadi. Defaultnya adalah sekarang jika dihilangkan."
                  },
                  "time_zone": {
                    "type": "string",
                    "description": "Pengenal zona waktu IANA, misalnya `Europe/Madrid`."
                  },
                  "transaction_category": {
                    "type": "string",
                    "description": "Kategori transaksi. Alias CamelCase (`travelRule`, `userPlatformEvent`, `gamblingBet`, …) juga diterima; nilai yang disimpan/dikembalikan berupa camelCase untuk kategori multi-kata.",
                    "example": "finance",
                    "enum": [
                      "finance",
                      "kyc",
                      "travel_rule",
                      "user_event",
                      "audit_trail_event",
                      "gambling_bet",
                      "gambling_limit_change",
                      "gambling_bonus_change",
                      "travelRule"
                    ]
                  },
                  "transaction_details": {
                    "type": "object",
                    "description": "Detail keuangan inti dari transaksi.",
                    "required": [
                      "direction",
                      "amount",
                      "currency"
                    ],
                    "properties": {
                      "direction": {
                        "type": "string",
                        "description": "Arah transaksi relatif terhadap subjek. Tidak peka huruf besar/kecil; `in`/`out` diterima sebagai alias. Dikembalikan dalam huruf besar (`INBOUND`/`OUTBOUND`).",
                        "example": "outbound",
                        "enum": [
                          "inbound",
                          "outbound",
                          "in",
                          "out"
                        ]
                      },
                      "amount": {
                        "type": "number",
                        "description": "Jumlah transaksi (hingga 18 tempat desimal). Kirimkan sebagai string desimal (misalnya `\"0.123456789012345678\"`) jika presisi tepat diperlukan: angka JSON diurai sebagai float biner terlebih dahulu, sehingga digit di luar sekitar 15 digit signifikan akan dibulatkan sebelum jumlah disimpan. Harus nol atau lebih besar: arah menentukan tanda, dan jumlah negatif menghasilkan `400`.",
                        "example": 1500
                      },
                      "currency": {
                        "type": "string",
                        "description": "Kode mata uang. Kode alfabet ISO 4217 apa pun diterima (misalnya `EUR`, `USD`, `NGN`), begitu pula simbol aset kripto (misalnya `BTC`). Sebaiknya gunakan kode yang saat ini beredar. Tidak semua kode yang diterima memiliki nilai tukar: jika tidak ada nilai tukar yang tersedia untuk kode tersebut (misalnya unit akuntansi ISO `XSU`, atau simbol kripto yang harganya tidak ditetapkan oleh Didit), konversi otomatis gagal dan `preferred_currency_amount` dikembalikan sebagai null kecuali permintaan menyertakan `amount_in_default_currency` yang telah dikonversi sebelumnya.",
                        "example": "EUR"
                      },
                      "currency_kind": {
                        "type": "string",
                        "description": "Apakah mata uang berupa `fiat` atau `crypto`."
                      },
                      "amount_in_default_currency": {
                        "type": "number",
                        "nullable": true,
                        "description": "Jumlah yang dikonversi sebelumnya dalam mata uang default. Jika dihilangkan, konversi valas otomatis akan dicoba. Harus bernilai nol atau lebih besar."
                      },
                      "default_currency": {
                        "type": "string",
                        "description": "Kode mata uang default untuk jumlah yang dikonversi. Kode ISO 4217 apa pun yang saat ini beredar."
                      },
                      "payment_details": {
                        "type": "string",
                        "nullable": true,
                        "description": "Referensi atau memo pembayaran teks bebas."
                      },
                      "payment_reference_id": {
                        "type": "string",
                        "nullable": true,
                        "description": "Referensi sistem pembayaran eksternal. Untuk skrining hash transaksi AML kripto, kirim hash transaksi blockchain dan berikan juga `subject.payment_method.account_id` dengan alamat terkait."
                      },
                      "action_type": {
                        "type": "string",
                        "nullable": true,
                        "description": "Subtipe transaksi, misalnya `deposit`, `withdrawal`, `transfer`."
                      },
                      "crypto_params": {
                        "type": "object",
                        "description": "Pemilihan jaringan kripto, terpisah dari mata uang (simbol aset). Mencatat simbol token kustom tidak menjamin cakupan hash transaksi untuk kontraknya.",
                        "properties": {
                          "crypto_chain": {
                            "type": "string",
                            "description": "Jaringan aktual yang digunakan untuk skrining. Skrining terkelola mendukung BTC, ETH, LTC, XRP, BCH, DOGE, TRX, SOL, MATIC, BNB, BASE (Base), OP (Optimism), ARB (Arbitrum One), AVAX (Avalanche C-Chain), ADA (Cardano), XLM (Stellar), dan HBAR (Hedera). Nama jaringan umum juga diterima, misalnya POLYGON atau POL untuk MATIC, BSC untuk BNB, dan TRON untuk TRX. Selalu tentukan parameter ini untuk token multi-jaringan. Jika tidak diisi untuk USDT, USDC, atau ETH yang dikirim dengan hash transaksi 0x, Didit akan mencari hash tersebut di Ethereum, BNB Chain, Polygon, Base, Arbitrum, dan Optimism, lalu melakukan skrining pada jaringan tempat hash ditemukan; jika tidak ditemukan di jaringan mana pun, transaksi tidak diskrining dan custom_values.aml_screening_status bernilai FAILED dengan alasannya di custom_values.aml_screening_error. Jika tidak diisi untuk USDT atau USDC yang diskrining berdasarkan dompet (tanpa hash transaksi), alamat Tron diskrining di Tron, alamat Solana di Solana, dan alamat 0x di jaringan pertama dari keenam jaringan tersebut tempat alamat tersebut pernah mengirim transaksi atau menyimpan token, atau di Ethereum jika tidak aktif di jaringan mana pun. Cakupan penyedia terhubung bervariasi; LIGHTNING memerlukan penyedia terhubung yang didukung.",
                            "example": "BASE"
                          }
                        }
                      }
                    }
                  },
                  "subject": {
                    "type": "object",
                    "description": "Subjek (pemohon) dari transaksi.",
                    "required": [
                      "vendor_data",
                      "full_name"
                    ],
                    "properties": {
                      "entity_type": {
                        "type": "string",
                        "description": "Tipe entitas: `individual` atau `company`."
                      },
                      "vendor_data": {
                        "type": "string",
                        "description": "Pengenal pengguna/bisnis internal Anda.",
                        "example": "user-12345"
                      },
                      "full_name": {
                        "type": "string",
                        "description": "Nama lengkap subjek.",
                        "example": "Maria Garcia"
                      },
                      "first_name": {
                        "type": "string",
                        "description": "Nama depan subjek."
                      },
                      "last_name": {
                        "type": "string",
                        "description": "Nama belakang subjek."
                      },
                      "date_of_birth": {
                        "type": "string",
                        "format": "date",
                        "description": "Tanggal lahir (YYYY-MM-DD)."
                      },
                      "address": {
                        "type": "object",
                        "description": "Objek alamat.",
                        "properties": {
                          "country": {
                            "type": "string",
                            "description": "Kode negara (disarankan ISO 3166-1 alpha-3). Disalin ke `country_code` pihak tersebut."
                          },
                          "town": {
                            "type": "string"
                          },
                          "state": {
                            "type": "string"
                          },
                          "street": {
                            "type": "string"
                          },
                          "post_code": {
                            "type": "string"
                          }
                        }
                      },
                      "institution_details": {
                        "type": "object",
                        "description": "Detail institusi (untuk subjek institusional).",
                        "properties": {
                          "name": {
                            "type": "string"
                          },
                          "code": {
                            "type": "string"
                          },
                          "address": {
                            "type": "object"
                          }
                        }
                      },
                      "device_context": {
                        "type": "object",
                        "description": "Konteks perangkat yang diambil pada saat transaksi. browser_family dan platform harus dikirim sebagai kunci tingkat atas eksplisit — keduanya tidak diturunkan dari user_agent. Alias camelCase device juga diterima pada permintaan.",
                        "properties": {
                          "fingerprint": {
                            "type": "string",
                            "description": "Sidik jari perangkat yang unik."
                          },
                          "persistent_device_id": {
                            "type": "string",
                            "description": "Pengidentifikasi perangkat lintas-sesi yang stabil (skema fingerprint v2)."
                          },
                          "user_agent": {
                            "type": "string",
                            "description": "String user agent browser atau aplikasi. Alias CamelCase: userAgent."
                          },
                          "browser_family": {
                            "type": "string",
                            "description": "Famili browser (misalnya Chrome, Firefox, Safari). Harus dikirim secara eksplisit — ini tidak diturunkan dari user_agent. Alias CamelCase: browserFamily."
                          },
                          "browser_version": {
                            "type": "string",
                            "description": "String versi browser. Harus dikirim secara eksplisit. Alias CamelCase: browserVersion."
                          },
                          "platform": {
                            "type": "string",
                            "description": "Pengenal platform (web, ios, android, macos, windows, linux). Harus dikirim secara eksplisit — ini tidak diturunkan dari user_agent."
                          },
                          "os_family": {
                            "type": "string",
                            "description": "Keluarga sistem operasi (misalnya iOS, Android, Windows). Alias CamelCase: osFamily."
                          },
                          "os_version": {
                            "type": "string",
                            "description": "String versi sistem operasi. Alias CamelCase: osVersion."
                          },
                          "accept_language": {
                            "type": "string",
                            "description": "Nilai header Accept-Language. Alias CamelCase: acceptLang."
                          },
                          "session_id": {
                            "type": "string",
                            "description": "Pengenal sesi untuk sesi pengguna saat ini. Disimpan dalam metadata. Alias CamelCase: sessionId."
                          },
                          "session_age_ms": {
                            "type": "number",
                            "description": "Usia sesi pengguna dalam milidetik pada saat transaksi. Alias CamelCase: sessionAgeMs."
                          },
                          "network_context": {
                            "type": "object",
                            "description": "Konteks jaringan dengan alamat IP dan geolokasi. Blok ipInfo tingkat atas juga digabungkan ke dalam objek ini.",
                            "properties": {
                              "ip_address": {
                                "type": "string",
                                "description": "Alamat IP klien. Alias CamelCase: ip."
                              },
                              "ip_country_code": {
                                "type": "string",
                                "description": "Negara dari IP yang ditentukan secara geografis (ISO 3166-1 alpha-3). Alias CamelCase: countryCode3."
                              },
                              "latitude": {
                                "type": "number",
                                "description": "Garis lintang geografis IP. Alias CamelCase: lat."
                              },
                              "longitude": {
                                "type": "number",
                                "description": "Garis bujur geografis IP. Alias CamelCase: lon."
                              }
                            }
                          }
                        }
                      },
                      "payment_method": {
                        "type": "object",
                        "description": "Metode pembayaran yang digunakan oleh subjek.",
                        "properties": {
                          "method_type": {
                            "type": "string",
                            "description": "Jenis metode pembayaran: `bank_card`, `bank_account`, `crypto_wallet`, `ewallet`, `unhosted_wallet`, `other`."
                          },
                          "account_id": {
                            "type": "string",
                            "description": "Pengidentifikasi akun (misalnya IBAN, alamat dompet). Untuk skrining kripto, ini harus berisi alamat dompet untuk partisipan ini. Skrining hash transaksi masuk memerlukan alamat deposit layanan/pelanggan pada subjek. Skrining keluar menggunakan dompet tujuan pada pihak lawan. Pada transfer kripto di bitcoin atau Lightning, ini dapat berupa permintaan pembayaran Lightning (faktur BOLT11, penawaran BOLT12, LNURL) atau Lightning Address: Didit menyimpan penerima pembayaran yang disebutkan sebagai akun (\"\" jika tidak menyebutkan siapa pun) dan apa yang tertera pada permintaan di `chain_details.lightning` transfer Travel Rule. Maksimal 255 karakter setelah disimpan. Pada transfer kripto di bitcoin atau Lightning, ini dapat berupa permintaan pembayaran Lightning (faktur BOLT11, penawaran BOLT12, LNURL) atau Lightning Address: Didit menyimpan penerima pembayaran yang disebutkan sebagai akun (\"\" jika tidak menyebutkan siapa pun) dan apa yang tertera pada permintaan di `chain_details.lightning` transfer Travel Rule. Maksimal 255 karakter setelah disimpan."
                          },
                          "memo": {
                            "type": "string",
                            "maxLength": 256,
                            "description": "Destination tag atau memo yang merupakan bagian dari dompet di jaringan memo (XRP, XLM, EOS, ATOM, HBAR). Pada satu alamat bursa bersama, setiap memo adalah metode pembayarannya sendiri. XRP: destination tag, bilangan bulat dari 0 hingga 4294967295 (angka JSON diterima). XLM: memo teks hingga 28 byte, ID 64-bit, atau hash 32-byte dalam heksadesimal. EOS: hingga 256 byte. ATOM: hingga 256 karakter. HBAR: hingga 100 byte. Dompet Bitcoin, EVM, Solana, Tron, Litecoin, Bitcoin Cash, Dogecoin, dan Lightning tidak memerlukan memo: keberadaan memo akan menghasilkan `400`. Alias: `destinationTag` atau `destination_tag`."
                          },
                          "issuing_country": {
                            "type": "string",
                            "description": "Kode negara ISO 3166-1 alpha-3 dari penerbit."
                          }
                        }
                      }
                    }
                  },
                  "counterparty": {
                    "type": "object",
                    "description": "Pihak lawan dari transaksi (opsional).",
                    "properties": {
                      "entity_type": {
                        "type": "string",
                        "description": "Tipe entitas: `individual` atau `company`."
                      },
                      "vendor_data": {
                        "type": "string",
                        "description": "Pengenal internal Anda untuk pihak lawan."
                      },
                      "full_name": {
                        "type": "string",
                        "description": "Nama lengkap pihak lawan."
                      },
                      "first_name": {
                        "type": "string"
                      },
                      "last_name": {
                        "type": "string"
                      },
                      "date_of_birth": {
                        "type": "string",
                        "format": "date"
                      },
                      "address": {
                        "type": "object",
                        "description": "Objek alamat dengan `country` (ISO 3166-1 alpha-3)."
                      },
                      "institution_details": {
                        "type": "object"
                      },
                      "device_context": {
                        "type": "object",
                        "description": "Konteks perangkat untuk pihak lawan. browser_family dan platform harus dikirim sebagai kunci tingkat atas eksplisit — keduanya tidak diturunkan dari user_agent.",
                        "properties": {
                          "fingerprint": {
                            "type": "string",
                            "description": "Sidik jari perangkat yang unik."
                          },
                          "persistent_device_id": {
                            "type": "string",
                            "description": "Pengidentifikasi perangkat lintas-sesi yang stabil (skema fingerprint v2)."
                          },
                          "user_agent": {
                            "type": "string",
                            "description": "String user agent browser atau aplikasi. Alias CamelCase: userAgent."
                          },
                          "browser_family": {
                            "type": "string",
                            "description": "Famili browser (misalnya Chrome, Firefox, Safari). Harus dikirim secara eksplisit — ini tidak diturunkan dari user_agent. Alias CamelCase: browserFamily."
                          },
                          "browser_version": {
                            "type": "string",
                            "description": "String versi browser. Harus dikirim secara eksplisit. Alias CamelCase: browserVersion."
                          },
                          "platform": {
                            "type": "string",
                            "description": "Pengenal platform (web, ios, android, macos, windows, linux). Harus dikirim secara eksplisit — ini tidak diturunkan dari user_agent."
                          },
                          "os_family": {
                            "type": "string",
                            "description": "Keluarga sistem operasi (misalnya iOS, Android, Windows). Alias CamelCase: osFamily."
                          },
                          "os_version": {
                            "type": "string",
                            "description": "String versi sistem operasi. Alias CamelCase: osVersion."
                          },
                          "accept_language": {
                            "type": "string",
                            "description": "Nilai header Accept-Language. Alias CamelCase: acceptLang."
                          },
                          "session_id": {
                            "type": "string",
                            "description": "Pengenal sesi untuk sesi pihak lawan. Disimpan dalam metadata. Alias CamelCase: sessionId."
                          },
                          "session_age_ms": {
                            "type": "number",
                            "description": "Usia sesi pengguna dalam milidetik pada saat transaksi. Alias CamelCase: sessionAgeMs."
                          },
                          "network_context": {
                            "type": "object",
                            "description": "Konteks jaringan dengan alamat IP dan geolokasi. Blok ipInfo tingkat atas juga digabungkan ke dalam objek ini.",
                            "properties": {
                              "ip_address": {
                                "type": "string",
                                "description": "Alamat IP klien. Alias CamelCase: ip."
                              },
                              "ip_country_code": {
                                "type": "string",
                                "description": "Negara dari IP yang ditentukan secara geografis (ISO 3166-1 alpha-3). Alias CamelCase: countryCode3."
                              },
                              "latitude": {
                                "type": "number",
                                "description": "Garis lintang geografis IP. Alias CamelCase: lat."
                              },
                              "longitude": {
                                "type": "number",
                                "description": "Garis bujur geografis IP. Alias CamelCase: lon."
                              }
                            }
                          }
                        }
                      },
                      "payment_method": {
                        "type": "object",
                        "description": "Metode pembayaran yang digunakan oleh pihak lawan. Pada transaksi travelRule, `method_type: \"unhosted_wallet\"` mendeklarasikan dompet pihak lawan sebagai dompet swakelola: transfer mengabaikan perutean VASP pihak lawan, dibuat langsung dalam `UNCONFIRMED_OWNERSHIP`, dan (ketika `auto_wallet_verification` diaktifkan) sesi widget kepemilikan dompet dibuat secara otomatis dan dikembalikan di blok `action_required` transaksi.",
                        "properties": {
                          "method_type": {
                            "type": "string",
                            "description": "Jenis metode pembayaran: `bank_card`, `bank_account`, `crypto_wallet`, `ewallet`, `unhosted_wallet`, `other`. Gunakan `unhosted_wallet` untuk mendeklarasikan dompet swakelola untuk Travel Rule."
                          },
                          "account_id": {
                            "type": "string",
                            "description": "Pengidentifikasi akun (misalnya IBAN atau alamat dompet). Pada transfer kripto di bitcoin atau Lightning, ini dapat berupa permintaan pembayaran Lightning (faktur BOLT11, penawaran BOLT12, LNURL) atau Lightning Address: Didit menyimpan penerima pembayaran yang disebutkan sebagai akun (\"\" jika tidak menyebutkan siapa pun) dan apa yang tertera pada permintaan di `chain_details.lightning` transfer Travel Rule. Maksimal 255 karakter setelah disimpan. Pada transfer kripto di bitcoin atau Lightning, ini dapat berupa permintaan pembayaran Lightning (faktur BOLT11, penawaran BOLT12, LNURL) atau Lightning Address: Didit menyimpan penerima pembayaran yang disebutkan sebagai akun (\"\" jika tidak menyebutkan siapa pun) dan apa yang tertera pada permintaan di `chain_details.lightning` transfer Travel Rule. Maksimal 255 karakter setelah disimpan."
                          },
                          "memo": {
                            "type": "string",
                            "maxLength": 256,
                            "description": "Destination tag atau memo yang merupakan bagian dari dompet di jaringan memo (XRP, XLM, EOS, ATOM, HBAR). Pada satu alamat bursa bersama, setiap memo adalah metode pembayarannya sendiri. XRP: destination tag, bilangan bulat dari 0 hingga 4294967295 (angka JSON diterima). XLM: memo teks hingga 28 byte, ID 64-bit, atau hash 32-byte dalam heksadesimal. EOS: hingga 256 byte. ATOM: hingga 256 karakter. HBAR: hingga 100 byte. Dompet Bitcoin, EVM, Solana, Tron, Litecoin, Bitcoin Cash, Dogecoin, dan Lightning tidak memerlukan memo: keberadaan memo akan menghasilkan `400`. Alias: `destinationTag` atau `destination_tag`."
                          },
                          "issuing_country": {
                            "type": "string"
                          }
                        }
                      }
                    }
                  },
                  "custom_properties": {
                    "type": "object",
                    "description": "Pasangan kunci-nilai arbitrer yang dilampirkan ke transaksi. Setiap kunci dapat dirujuk dalam kondisi aturan dengan jalur kolom `custom_values.<key>`.",
                    "additionalProperties": true,
                    "example": {
                      "merchant_id": "test",
                      "bank_name": "test_2"
                    }
                  },
                  "travel_rule_details": {
                    "type": "object",
                    "description": "Data Travel Rule. Saat Travel Rule diaktifkan dan transaction_category adalah travel_rule, Didit menjalankan pertukaran itu sendiri: mengabaikan status, protocol, required, dan obligations_count, serta menggunakan originator_data, beneficiary_data, dan metadata. Jika tidak, Didit menyimpan nilai-nilai ini sebagai catatan Travel Rule pasif. Saat Travel Rule aktif, transfer keluar pada atau di atas ambang batas Anda harus menyertakan apa yang diwajibkan oleh rezimnya (EU TFR atau Rekomendasi FATF 16), yang diperiksa pada sisi yang Anda kirim: kolom yang hilang menghasilkan respons 400 di bawah `travel_rule_details.originator_data` atau `travel_rule_details.beneficiary_data`, misalnya \"EU TFR mewajibkan nama pengirim.\"",
                    "required": [
                      "status"
                    ],
                    "properties": {
                      "status": {
                        "type": "string",
                        "description": "Wajib diisi setiap kali Anda mengirim travel_rule_details. Salah satu status transfer Travel Rule (misalnya AWAITING_COUNTERPARTY, COMPLETED, NOT_APPLICABLE); penulisan huruf kecil dan camelCase serta nilai lama UNKNOWN, COMPLIANT, PENDING_ACTION, PENDING_COUNTERPARTY, FAILED, dan EXEMPT juga diterima dan dipetakan. Nilai lain apa pun mengembalikan 400."
                      },
                      "protocol": {
                        "type": "string"
                      },
                      "required": {
                        "type": "boolean"
                      },
                      "obligations_count": {
                        "type": "integer"
                      },
                      "originator_data": {
                        "type": "object",
                        "description": "Pihak pengirim, sebagai kolom datar atau satu individu IVMS 101. Untuk pengguna Anda dengan verifikasi KYC yang disetujui, Didit mengganti kolom yang tercakup dalam verifikasi dengan nilai yang terverifikasi (lihat `metadata.originator_provenance`). Harus berupa objek: format lainnya menghasilkan `400`. Pada jaringan memo, kunci `memo` menyebutkan memo atau tag dompet pengirim."
                      },
                      "beneficiary_data": {
                        "type": "object",
                        "description": "Pihak penerima, sebagai kolom datar atau satu individu IVMS 101. Nilainya harus berupa objek: selain itu akan menghasilkan `400`. Untuk merutekan transfer, Didit membaca `wallet_address` (yang kosong diisi dari `counterparty.payment_method.account_id`), `chain` (diisi dari `transaction_details.crypto_params.crypto_chain` atau `currency` jika menyebutkan rantai yang didukung), `name` (menggunakan cadangan `counterparty.full_name`), `travel_address`, `counterparty_vasp_name`, `counterparty_vasp_lei`, dan `counterparty_vasp_email`. Pada jaringan memo, `memo` menentukan memo atau tag dompet penerima; `wallet_address` dan `memo` diprioritaskan di atas metode pembayaran pihak lawan."
                      },
                      "metadata": {
                        "type": "object"
                      },
                      "utxo": {
                        "allOf": [
                          {
                            "$ref": "#/components/schemas/TravelRuleUtxo"
                          }
                        ],
                        "description": "Opsional, hanya rantai UTXO (BTC, LTC, BCH, DOGE). Input dan output transaksi, yang darinya Didit menyimpulkan dompet pengirim dan output penerima saat Anda tidak mendeklarasikannya."
                      },
                      "originator": {
                        "type": "object",
                        "description": "Blok pengirim IVMS 101: `originatorPersons` (satu `naturalPerson` atau `legalPerson`; badan hukum menjadikan pihak tersebut sebuah perusahaan) dan `accountNumber` (alamat). Digunakan untuk `originator_data` saat objek tersebut kosong. Blok yang salah format mengembalikan respons 400 dengan kunci jalurnya, misalnya `originator.originatorPersons`."
                      },
                      "beneficiary": {
                        "type": "object",
                        "description": "Blok penerima IVMS 101: `beneficiaryPersons` (satu `naturalPerson` atau `legalPerson`; badan hukum menjadikan pihak tersebut sebuah perusahaan) dan `accountNumber` (alamat). Digunakan untuk `beneficiary_data` saat objek tersebut kosong. Blok yang salah format mengembalikan respons 400 dengan kunci jalurnya, misalnya `beneficiary.beneficiaryPersons`."
                      },
                      "ivms101": {
                        "type": "object",
                        "description": "Blok `originator` dan `beneficiary` yang dibungkus dalam satu objek IVMS 101 (`IVMS101` juga diterima). Blok tingkat atas lebih diutamakan daripada blok pembungkus."
                      }
                    }
                  },
                  "network_snapshot": {
                    "type": "object",
                    "description": "Snapshot graf jaringan yang dihitung sebelumnya.",
                    "properties": {
                      "nodes": {
                        "type": "array",
                        "items": {
                          "type": "object"
                        }
                      },
                      "edges": {
                        "type": "array",
                        "items": {
                          "type": "object"
                        }
                      },
                      "metrics": {
                        "type": "object"
                      }
                    }
                  },
                  "include_crypto_screening": {
                    "type": "boolean",
                    "nullable": true,
                    "description": "Override per transaksi untuk skrining analitik blockchain kripto. Jika bernilai `true`, skrining kripto dilakukan terlepas dari default aplikasi. Jika bernilai `false`, skrining kripto dilewati meskipun diaktifkan dalam pengaturan aplikasi. Jika dihilangkan atau `null`, default tingkat aplikasi yang dikonfigurasikan di Console akan digunakan. Skrining kripto memerlukan `transaction_details.direction`, `currency_kind: \"crypto\"`, rantai/mata uang, dan alamat dompet yang dipilih berdasarkan arah: skrining pra-transfer masuk menggunakan `counterparty.payment_method.account_id`, skrining hash transaksi masuk menggunakan `subject.payment_method.account_id`, dan skrining keluar menggunakan `counterparty.payment_method.account_id`. Jika `transaction_details.payment_reference_id` berisi hash transaksi blockchain, Didit melakukan skrining transaksi dan mengembalikan pengayaan ringkasan transaksi jika tersedia."
                  }
                },
                "required": [
                  "transaction_id",
                  "transaction_category",
                  "transaction_details",
                  "subject"
                ]
              },
              "examples": {
                "Minimal fiat withdrawal": {
                  "summary": "Payload terkecil yang dapat diterima untuk transfer keluar fiat",
                  "value": {
                    "transaction_id": "your-txn-2026-05-17-001",
                    "transaction_category": "finance",
                    "transaction_details": {
                      "direction": "outbound",
                      "amount": 1500,
                      "currency": "EUR",
                      "action_type": "withdrawal"
                    },
                    "subject": {
                      "entity_type": "individual",
                      "vendor_data": "user-12345",
                      "full_name": "Maria Garcia"
                    }
                  }
                },
                "Crypto outbound with screening": {
                  "summary": "Penarikan kripto keluar ke dompet swakelola, skrining opsional (opt-in)",
                  "value": {
                    "transaction_id": "your-txn-2026-05-17-002",
                    "transaction_category": "finance",
                    "include_crypto_screening": true,
                    "transaction_details": {
                      "direction": "outbound",
                      "amount": 0.5,
                      "currency": "BTC",
                      "currency_kind": "crypto",
                      "amount_in_default_currency": 32500,
                      "default_currency": "USD",
                      "action_type": "withdrawal"
                    },
                    "subject": {
                      "entity_type": "individual",
                      "vendor_data": "user-12345",
                      "full_name": "Maria Garcia",
                      "payment_method": {
                        "method_type": "crypto_wallet",
                        "account_id": "bc1qexampleexchangewalletaddressxyz",
                        "issuing_country": "ESP"
                      }
                    },
                    "counterparty": {
                      "entity_type": "individual",
                      "payment_method": {
                        "method_type": "unhosted_wallet",
                        "account_id": "bc1qexampleexternalwalletaddressabc"
                      }
                    }
                  }
                },
                "Travel Rule transfer": {
                  "summary": "Transfer kripto keluar dengan data pengirim/penerima Travel Rule",
                  "value": {
                    "transaction_id": "your-txn-2026-05-17-003",
                    "transaction_category": "travel_rule",
                    "transaction_details": {
                      "direction": "outbound",
                      "amount": 25000,
                      "currency": "USDT",
                      "currency_kind": "crypto",
                      "action_type": "transfer"
                    },
                    "subject": {
                      "entity_type": "individual",
                      "vendor_data": "user-12345",
                      "full_name": "Maria Garcia",
                      "date_of_birth": "1992-03-14",
                      "address": {
                        "country": "ESP",
                        "town": "Madrid",
                        "street": "Calle Mayor 1",
                        "post_code": "28013"
                      }
                    },
                    "counterparty": {
                      "entity_type": "individual",
                      "full_name": "John Beneficiary",
                      "institution_details": {
                        "name": "Beneficiary VASP, Inc.",
                        "code": "BVASP-US"
                      }
                    },
                    "travel_rule_details": {
                      "status": "AWAITING_COUNTERPARTY",
                      "protocol": "IVMS101",
                      "required": true,
                      "originator_data": {
                        "name": "Maria Garcia"
                      },
                      "beneficiary_data": {
                        "name": "John Beneficiary"
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Transaksi dikirimkan dan dipantau. Isi adalah detail transaksi lengkap (bentuk yang sama dengan `GET /v3/transactions/{transaction_id}/`), yang mencerminkan hasil aturan apa pun yang telah diterapkan.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TransactionDetail"
                },
                "examples": {
                  "Approved with no rule hits": {
                    "value": {
                      "uuid": "abcdef12-3456-4890-abcd-ef1234567890",
                      "environment": "live",
                      "transaction_number": 4123,
                      "txn_id": "your-txn-2026-05-17-001",
                      "txn_date": "2026-05-17T08:42:00Z",
                      "zone_id": "Europe/Madrid",
                      "transaction_type": "finance",
                      "action_type": "withdrawal",
                      "direction": "OUTBOUND",
                      "status": "APPROVED",
                      "source": "LIVE",
                      "amount": "1500",
                      "currency": "EUR",
                      "currency_type": "fiat",
                      "amount_in_default_currency": "1620.45",
                      "default_currency_code": "USD",
                      "preferred_currency_amount": "1620.45",
                      "preferred_currency_code": "USD",
                      "payment_details": "Withdrawal to crypto wallet",
                      "payment_txn_id": null,
                      "score": 0,
                      "severity": null,
                      "decision_reason_code": null,
                      "decision_reason_label": null,
                      "vendor_data": "user-12345",
                      "metadata": {
                        "subject": {
                          "entity_type": "individual",
                          "vendor_data": "user-12345",
                          "full_name": "Maria Garcia",
                          "address": {},
                          "institution_details": {},
                          "device_context": {}
                        },
                        "counterparty": {}
                      },
                      "props": {},
                      "tags": [],
                      "parties": [
                        {
                          "uuid": "b1111111-2222-4333-8444-555555555555",
                          "role": "APPLICANT",
                          "entity_type": "individual",
                          "kind": "USER",
                          "vendor_data": "user-12345",
                          "full_name": "Maria Garcia",
                          "first_name": null,
                          "last_name": null,
                          "country_code": null,
                          "dob": null,
                          "address": {},
                          "institution_info": {},
                          "device": {},
                          "external_party_snapshot": null
                        }
                      ],
                      "payment_methods": [],
                      "documents": [],
                      "activities": [
                        {
                          "uuid": "d4e5f6a7-8901-4bcd-9ef0-123456789abc",
                          "activity_type": "TRANSACTION_CREATED",
                          "source": "TRANSACTION",
                          "status": "APPROVED",
                          "title": "withdrawal",
                          "description": "Transaction recorded.",
                          "metadata": {},
                          "occurred_at": "2026-05-17T08:42:11Z"
                        }
                      ],
                      "alerts": [],
                      "rule_runs": [],
                      "provider_results": [],
                      "travel_rule": null,
                      "network_snapshot": null,
                      "remediation": null,
                      "action_required": null,
                      "cost_breakdown": null
                    }
                  },
                  "Flagged for review": {
                    "value": {
                      "uuid": "abcdef12-3456-4890-abcd-ef1234567891",
                      "environment": "live",
                      "transaction_number": 4124,
                      "txn_id": "your-txn-2026-05-17-002",
                      "txn_date": "2026-05-17T08:42:00Z",
                      "zone_id": "Europe/Madrid",
                      "transaction_type": "finance",
                      "action_type": "withdrawal",
                      "direction": "OUTBOUND",
                      "status": "IN_REVIEW",
                      "source": "LIVE",
                      "amount": "0.5",
                      "currency": "BTC",
                      "currency_type": "crypto",
                      "amount_in_default_currency": "32500",
                      "default_currency_code": "USD",
                      "preferred_currency_amount": "32500",
                      "preferred_currency_code": "USD",
                      "payment_details": "Withdrawal to crypto wallet",
                      "payment_txn_id": null,
                      "score": 78,
                      "severity": "HIGH",
                      "decision_reason_code": "WALLET_HIGH_RISK",
                      "decision_reason_label": "Destination wallet flagged as high risk",
                      "vendor_data": "user-12345",
                      "metadata": {
                        "subject": {
                          "entity_type": "individual",
                          "vendor_data": "user-12345",
                          "full_name": "Maria Garcia",
                          "address": {},
                          "institution_details": {},
                          "device_context": {}
                        },
                        "counterparty": {}
                      },
                      "props": {
                        "order_id": "ord-9988"
                      },
                      "tags": [],
                      "parties": [
                        {
                          "uuid": "b1111111-2222-4333-8444-555555555555",
                          "role": "APPLICANT",
                          "entity_type": "individual",
                          "kind": "USER",
                          "vendor_data": "user-12345",
                          "full_name": "Maria Garcia",
                          "first_name": null,
                          "last_name": null,
                          "country_code": null,
                          "dob": null,
                          "address": {},
                          "institution_info": {},
                          "device": {},
                          "external_party_snapshot": null
                        }
                      ],
                      "payment_methods": [],
                      "documents": [],
                      "activities": [],
                      "alerts": [
                        {
                          "uuid": "a7b8c9d0-1234-4abc-9def-567890abcdef",
                          "title": "Destination wallet flagged as high risk",
                          "description": "Provider risk score exceeded the configured threshold.",
                          "severity": "HIGH",
                          "status": "OPEN",
                          "source": "RULE",
                          "metadata": {},
                          "created_at": "2026-05-17T08:42:12Z",
                          "due_at": null
                        }
                      ],
                      "rule_runs": [
                        {
                          "uuid": "e5f6a7b8-9012-4cde-af01-23456789abcd",
                          "rule": "f6a7b8c9-0123-4def-b012-3456789abcde",
                          "rule_title": "High-risk wallet screening",
                          "rule_description": null,
                          "rule_category": "crypto",
                          "matched": true,
                          "is_test": false,
                          "mode": "ACTIVE",
                          "severity": "HIGH",
                          "score_delta": 78,
                          "status_target": "IN_REVIEW",
                          "action_summary": "score +78; change_status:IN_REVIEW",
                          "metadata": {},
                          "created_at": "2026-05-17T08:42:12Z"
                        }
                      ],
                      "provider_results": [],
                      "travel_rule": null,
                      "network_snapshot": null,
                      "remediation": null,
                      "action_required": null,
                      "cost_breakdown": null
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validasi gagal (kolom wajib tidak ada, duplikasi `transaction_id`, nilai enum tidak dikenal, mata uang tidak valid, dll.).",
            "content": {
              "application/json": {
                "examples": {
                  "Missing required field": {
                    "value": {
                      "transaction_details": {
                        "amount": [
                          "This field is required."
                        ]
                      }
                    }
                  },
                  "Duplicate transaction_id": {
                    "value": {
                      "transaction_id": [
                        "A transaction with this transaction_id already exists."
                      ]
                    }
                  },
                  "Invalid category": {
                    "value": {
                      "non_field_errors": [
                        "Unsupported transaction category."
                      ]
                    }
                  },
                  "Missing subject identity": {
                    "value": {
                      "subject": [
                        "subject.vendor_data and subject.full_name are required."
                      ]
                    }
                  },
                  "Blocklisted participant": {
                    "value": {
                      "vendor_data": [
                        "The individual 'user-12345' is in the blocklist and cannot participate in transactions."
                      ]
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Kunci API tidak ada, tidak valid, atau dicabut, atau kunci tersebut tidak dapat mengirimkan transaksi untuk aplikasi ini. Kunci yang tidak ada mengembalikan `403`; kunci yang salah, dicabut, atau kedaluwarsa mengembalikan `401`.",
            "content": {
              "application/json": {
                "examples": {
                  "Forbidden": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "Permintaan lain dengan `transaction_id` yang sama membuat transaksi saat permintaan ini sedang diproses, sehingga hanya satu dari dua pengiriman simultan yang berhasil. Baca transaksi yang ada alih-alih mengirim ulang.",
            "content": {
              "application/json": {
                "examples": {
                  "Concurrent duplicate": {
                    "value": {
                      "detail": "A transaction with this transaction_id already exists."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Batas laju terlampaui: pembuatan transaksi dan penyerapan event (`POST /v3/transactions/`, `POST /v3/events/`, `POST /v3/events/batch/`) berbagi anggaran sebanyak 600 permintaan per menit per kunci API, terpisah dari anggaran 300 permintaan yang digunakan bersama oleh semua permintaan tulis lainnya. Tunggu `Retry-After` detik, lalu coba lagi.",
            "headers": {
              "Retry-After": {
                "description": "Detik yang harus ditunggu sebelum mencoba lagi, dibulatkan ke atas agar percobaan berikutnya berada di jendela berikutnya.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "example": 30
                }
              }
            },
            "content": {
              "application/json": {
                "examples": {
                  "Throttled": {
                    "value": {
                      "detail": "Ingestion rate limit exceeded. You can make up to 600 requests per minute."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-didit-sdk": {
          "resource": "transactions",
          "method": "create",
          "auth": "api_key",
          "server": true
        }
      }
    },
    "/v3/transactions/{transaction_id}/": {
      "get": {
        "summary": "Dapatkan transaksi",
        "description": "Ambil rekaman pemantauan lengkap untuk satu transaksi: para pihak, skor/tingkat keparahan, eksekusi aturan, alert, hasil Travel Rule, sesi remediasi.",
        "operationId": "getTransaction",
        "x-didit-sdk": {
          "resource": "transactions",
          "method": "retrieve",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Transactions"
        ],
        "parameters": [
          {
            "name": "transaction_id",
            "in": "path",
            "required": true,
            "description": "UUID transaksi yang stabil dari Didit (`uuid` yang dikembalikan dari pembuatan / daftar, **bukan** `txn_id` Anda).",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "abcdef12-3456-7890-abcd-ef1234567890"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/transactions/abcdef12-3456-7890-abcd-ef1234567890/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.transactions.retrieve(\n    \"abcdef12-3456-7890-abcd-ef1234567890\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.transactions.retrieve(\"abcdef12-3456-7890-abcd-ef1234567890\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Transactions.Retrieve(ctx, \"abcdef12-3456-7890-abcd-ef1234567890\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.transactions().retrieve(\"abcdef12-3456-7890-abcd-ef1234567890\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->transactions->retrieve('abcdef12-3456-7890-abcd-ef1234567890');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.transactions.retrieve(\"abcdef12-3456-7890-abcd-ef1234567890\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Transactions.RetrieveAsync(\"abcdef12-3456-7890-abcd-ef1234567890\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "Detail transaksi lengkap.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TransactionDetail"
                },
                "examples": {
                  "In review with an alert": {
                    "value": {
                      "uuid": "abcdef12-3456-4890-abcd-ef1234567890",
                      "environment": "live",
                      "transaction_number": 4123,
                      "txn_id": "your-txn-2026-05-17-001",
                      "txn_date": "2026-05-17T08:42:00Z",
                      "zone_id": "Europe/Madrid",
                      "transaction_type": "finance",
                      "action_type": "withdrawal",
                      "direction": "OUTBOUND",
                      "status": "IN_REVIEW",
                      "source": "LIVE",
                      "amount": "1500",
                      "currency": "EUR",
                      "currency_type": "fiat",
                      "amount_in_default_currency": "1620.45",
                      "default_currency_code": "USD",
                      "preferred_currency_amount": "1620.45",
                      "preferred_currency_code": "USD",
                      "payment_details": "Withdrawal to crypto wallet",
                      "payment_txn_id": null,
                      "score": 78,
                      "severity": "HIGH",
                      "decision_reason_code": "WALLET_HIGH_RISK",
                      "decision_reason_label": "Destination wallet flagged as high risk",
                      "vendor_data": "user-12345",
                      "metadata": {
                        "subject": {
                          "entity_type": "individual",
                          "vendor_data": "user-12345",
                          "full_name": "Maria Garcia",
                          "address": {},
                          "institution_details": {},
                          "device_context": {}
                        },
                        "counterparty": {}
                      },
                      "props": {
                        "order_id": "ord-9988"
                      },
                      "tags": [],
                      "parties": [
                        {
                          "uuid": "b1111111-2222-4333-8444-555555555555",
                          "role": "APPLICANT",
                          "entity_type": "individual",
                          "kind": "USER",
                          "vendor_data": "user-12345",
                          "full_name": "Maria Garcia",
                          "first_name": null,
                          "last_name": null,
                          "country_code": null,
                          "dob": null,
                          "address": {},
                          "institution_info": {},
                          "device": {},
                          "external_party_snapshot": null
                        }
                      ],
                      "payment_methods": [],
                      "documents": [],
                      "activities": [],
                      "alerts": [
                        {
                          "uuid": "a7b8c9d0-1234-4abc-9def-567890abcdef",
                          "title": "Destination wallet flagged as high risk",
                          "description": "Provider risk score exceeded the configured threshold.",
                          "severity": "HIGH",
                          "status": "OPEN",
                          "source": "RULE",
                          "metadata": {},
                          "created_at": "2026-05-17T08:42:12Z",
                          "due_at": null
                        }
                      ],
                      "rule_runs": [],
                      "provider_results": [],
                      "travel_rule": null,
                      "network_snapshot": null,
                      "remediation": null,
                      "action_required": null,
                      "cost_breakdown": null
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Kunci API tidak ada, tidak valid, atau dicabut, atau kunci tersebut tidak dapat membaca transaksi aplikasi ini. Kunci yang tidak ada mengembalikan `403`; kunci yang salah, dicabut, atau kedaluwarsa mengembalikan `401`.",
            "content": {
              "application/json": {
                "examples": {
                  "Forbidden": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Tidak ada transaksi dengan UUID ini untuk aplikasi tersebut (dihapus, tidak pernah dibuat, milik aplikasi lain, atau segmen path bukan UUID yang valid).",
            "content": {
              "application/json": {
                "examples": {
                  "Not found": {
                    "value": {
                      "detail": "Not found."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Batas laju terlampaui; kurangi laju permintaan dan coba lagi setelah interval yang ditunjukkan dalam `Retry-After`.",
            "content": {
              "application/json": {
                "examples": {
                  "Throttled": {
                    "value": {
                      "detail": "Request was throttled. Expected available in 30 seconds."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/transactions/sdk-token/": {
      "post": {
        "summary": "Buat token transaksi SDK",
        "description": "Buat token berumur pendek dengan cakupan terbatas yang diteruskan oleh aplikasi Anda ke SDK Didit sehingga dapat mengirimkan transaksi langsung dari perangkat pengguna akhir melalui `POST /v1/transactions/`. Token ini terikat pada satu `vendor_data` (ID pengguna Anda): identitas subjek dari setiap transaksi yang dikirimkan dengannya diberlakukan di sisi server berdasarkan pengikatan tersebut, sehingga klien yang dimanipulasi tidak dapat mengirimkan atas nama pengguna lain. Buat token dari backend Anda - jangan pernah menyertakan kunci API itu sendiri dalam aplikasi. Alias camelCase (`vendorData`, `ttlSeconds`, `maxUses`) juga diterima.",
        "operationId": "createTransactionSdkToken",
        "x-didit-sdk": {
          "resource": "transactions",
          "method": "create_sdk_token",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Transactions"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "vendor_data": {
                    "type": "string",
                    "description": "Pengenal internal Anda untuk pengguna akhir yang menjadi cakupan token ini. Diberlakukan sebagai identitas subjek dari setiap transaksi yang dikirimkan bersama token tersebut.",
                    "example": "user-042"
                  },
                  "ttl_seconds": {
                    "type": "integer",
                    "default": 900,
                    "maximum": 86400,
                    "description": "Masa berlaku token dalam detik. Defaultnya 900 (15 menit); maksimum 86400 (24 jam)."
                  },
                  "max_uses": {
                    "type": "integer",
                    "nullable": true,
                    "description": "Jumlah maksimum pengiriman yang berhasil yang diizinkan dengan token ini. Abaikan atau gunakan null untuk penggunaan tanpa batas dalam TTL."
                  }
                },
                "required": [
                  "vendor_data"
                ]
              },
              "example": {
                "vendor_data": "user-042",
                "ttl_seconds": 900,
                "max_uses": 3
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST https://verification.didit.me/v3/transactions/sdk-token/ \\\n  -H 'x-api-key: YOUR_API_KEY' -H 'Content-Type: application/json' \\\n  -d '{\"vendor_data\": \"user-042\", \"ttl_seconds\": 900, \"max_uses\": 3}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.transactions.create_sdk_token(\n    vendor_data=\"user-042\",\n    ttl_seconds=900,\n    max_uses=3,\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.transactions.createSdkToken({\n  vendor_data: \"user-042\",\n  ttl_seconds: 900,\n  max_uses: 3,\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Transactions.CreateSDKToken(ctx, didit.TransactionsCreateSDKTokenParams{\n\tVendorData: \"user-042\",\n\tTTLSeconds: didit.Int(900),\n\tMaxUses:    didit.Int(3),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.TransactionsCreateSdkTokenParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.transactions().createSdkToken(TransactionsCreateSdkTokenParams.builder()\n        .vendorData(\"user-042\")\n        .ttlSeconds(900L)\n        .maxUses(3L)\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->transactions->createSdkToken([\n    'vendor_data' => 'user-042',\n    'ttl_seconds' => 900,\n    'max_uses' => 3,\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.transactions.create_sdk_token(\n  vendor_data: \"user-042\",\n  ttl_seconds: 900,\n  max_uses: 3\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Transactions.CreateSdkTokenAsync(new TransactionsCreateSdkTokenParams\n{\n    VendorData = \"user-042\",\n    TtlSeconds = 900,\n    MaxUses = 3,\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "201": {
            "description": "Token yang diterbitkan. Berikan `sdk_token` ke aplikasi Anda; token ini mengautentikasi endpoint `/v1/transactions/` yang ditujukan untuk perangkat melalui header `X-Transaction-Token` hingga `expires_at`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "sdk_token": {
                      "type": "string",
                      "description": "Token transaksi dengan cakupan terbatas untuk diteruskan ke SDK."
                    },
                    "expires_at": {
                      "type": "string",
                      "format": "date-time",
                      "description": "Kapan token berhenti diterima."
                    }
                  }
                },
                "example": {
                  "sdk_token": "q7Zt...urlsafe",
                  "expires_at": "2026-07-07T12:15:00Z"
                }
              }
            }
          },
          "400": {
            "description": "Validasi gagal: `vendor_data` tidak ada, atau `ttl_seconds` di luar rentang yang diizinkan.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing vendor_data": {
                    "value": {
                      "vendor_data": [
                        "This field is required."
                      ]
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Kunci API tidak ada, tidak valid, atau dicabut.",
            "content": {
              "application/json": {
                "examples": {
                  "Invalid API Key": {
                    "value": {
                      "detail": "Invalid API Key."
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/transactions/": {
      "post": {
        "summary": "Kirim transaksi dari SDK",
        "description": "Endpoint yang menghadap perangkat yang dipanggil oleh SDK Didit untuk mengirimkan transaksi langsung dari perangkat pengguna akhir. Autentikasi berupa token dengan cakupan terbatas dari `POST /v3/transactions/sdk-token/` yang dikirim dalam header `X-Transaction-Token` alih-alih kunci API, dan endpoint ini mengaktifkan CORS sehingga browser dapat memanggilnya secara lintas asal (cross-origin). Payload menggunakan alias transmisi camelCase yang ditampilkan di bawah ini (metode `submitTransaction` SDK menyusunnya untuk Anda). Tiga jaminan sisi server: aplikasi selalu diambil dari token; identitas subjek (`externalUserId`) selalu diberlakukan dari `vendor_data` token, sehingga nilai payload palsu diabaikan; dan intelijen perangkat (sidik jari perangkat SDK ditambah IP serta user agent yang diturunkan dari server) dilampirkan ke subjek secara otomatis.",
        "operationId": "submitTransactionFromSdk",
        "x-didit-sdk": {
          "resource": "transactions",
          "method": "submit_from_device",
          "auth": "device_token",
          "server": false
        },
        "tags": [
          "Transactions"
        ],
        "security": [
          {
            "TransactionTokenAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "txnId": {
                    "type": "string",
                    "description": "Pengidentifikasi unik Anda untuk transaksi ini (dipetakan ke `transaction_id`, maks 128 karakter).",
                    "example": "wd-2026-07-07-0042"
                  },
                  "txnDate": {
                    "type": "string",
                    "format": "date-time",
                    "description": "Kapan transaksi terjadi (memetakan ke `transaction_at`). Defaultnya adalah sekarang jika dihilangkan."
                  },
                  "zoneId": {
                    "type": "string",
                    "description": "Pengenal zona waktu IANA (memetakan ke `time_zone`), misalnya `Europe/Madrid`."
                  },
                  "type": {
                    "type": "string",
                    "description": "Kategori transaksi (dipetakan ke `transaction_category`), misalnya `finance`, `kyc`, `travelRule`, `userPlatformEvent`, `gamblingBet`.",
                    "example": "travelRule"
                  },
                  "info": {
                    "type": "object",
                    "description": "Detail keuangan inti dari transaksi (memetakan ke `transaction_details`).",
                    "required": [
                      "direction",
                      "amount",
                      "currency"
                    ],
                    "properties": {
                      "direction": {
                        "type": "string",
                        "description": "Arah relatif terhadap subjek. Tidak peka huruf besar/kecil; `in`/`out` diterima sebagai alias. Dikembalikan dalam huruf besar (`INBOUND`/`OUTBOUND`).",
                        "example": "out"
                      },
                      "amount": {
                        "type": "number",
                        "description": "Jumlah transaksi (hingga 18 tempat desimal). String desimal juga diterima dan merupakan satu-satunya cara untuk mempertahankan lebih dari sekitar 15 digit signifikan: angka JSON diurai sebagai float biner terlebih dahulu, sehingga `0.123456789012345678` disimpan sebagai `0.12345678901234568`.",
                        "example": 0.25
                      },
                      "currency": {
                        "type": "string",
                        "description": "Kode mata uang. Kode alfabet ISO 4217 apa pun diterima (misalnya `EUR`, `USD`, `NGN`), begitu pula simbol aset kripto (misalnya `BTC`). Sebaiknya gunakan kode yang saat ini beredar. Tidak semua kode yang diterima memiliki nilai tukar: jika tidak ada nilai tukar yang tersedia untuk kode tersebut (misalnya unit akuntansi ISO `XSU`, atau simbol kripto yang harganya tidak ditetapkan oleh Didit), konversi otomatis gagal dan `preferred_currency_amount` dikembalikan sebagai null kecuali permintaan menyertakan `amountInDefaultCurrency` yang telah dikonversi sebelumnya.",
                        "example": "ETH"
                      },
                      "currencyType": {
                        "type": "string",
                        "description": "Apakah mata uang berupa `fiat` atau `crypto` (memetakan ke `currency_kind`)."
                      },
                      "amountInDefaultCurrency": {
                        "type": "number",
                        "nullable": true,
                        "description": "Jumlah yang dikonversi sebelumnya dalam mata uang default (dipetakan ke `amount_in_default_currency`). Jika dihilangkan, konversi valas otomatis akan dicoba."
                      },
                      "defaultCurrencyCode": {
                        "type": "string",
                        "description": "Kode mata uang default untuk jumlah yang dikonversi (memetakan ke `default_currency`). Kode ISO 4217 apa pun yang saat ini beredar."
                      },
                      "paymentDetails": {
                        "type": "string",
                        "nullable": true,
                        "description": "Referensi atau memo pembayaran teks bebas (dipetakan ke `payment_details`)."
                      },
                      "paymentTxnId": {
                        "type": "string",
                        "nullable": true,
                        "description": "Referensi pembayaran eksternal (dipetakan ke `payment_reference_id`); hash transaksi on-chain untuk transaksi kripto."
                      },
                      "type": {
                        "type": "string",
                        "nullable": true,
                        "description": "Subtipe transaksi (dipetakan ke `action_type`), misalnya `deposit`, `withdrawal`, `transfer`."
                      },
                      "cryptoParams": {
                        "type": "object",
                        "description": "Parameter khusus kripto, misalnya `{\"crypto_chain\": \"ETH\"}`."
                      }
                    }
                  },
                  "subject": {
                    "type": "object",
                    "description": "Subjek (pemohon) transaksi. `externalUserId` diabaikan di sini: identitas subjek selalu ditetapkan berdasarkan `vendor_data` token.",
                    "required": [
                      "fullName"
                    ],
                    "properties": {
                      "type": {
                        "type": "string",
                        "description": "Tipe entitas (dipetakan ke `entity_type`): `individual` (default) atau `company`."
                      },
                      "externalUserId": {
                        "type": "string",
                        "description": "Diabaikan pada subjek - diberlakukan di sisi server berdasarkan `vendor_data` pada token."
                      },
                      "fullName": {
                        "type": "string",
                        "example": "Jane Doe"
                      },
                      "firstName": {
                        "type": "string"
                      },
                      "lastName": {
                        "type": "string"
                      },
                      "dob": {
                        "type": "string",
                        "format": "date",
                        "description": "Tanggal lahir (YYYY-MM-DD; dipetakan ke `date_of_birth`)."
                      },
                      "address": {
                        "type": "object",
                        "description": "Objek alamat dengan `country` (ISO 3166-1 alpha-3), `town`, `state`, `street`, `post_code`."
                      },
                      "institutionInfo": {
                        "type": "object",
                        "description": "Detail institusi untuk peserta institusional (memetakan ke `institution_details`)."
                      },
                      "device": {
                        "type": "object",
                        "description": "Konteks perangkat eksplisit opsional. Digabungkan dengan data intelijen perangkat yang diambil secara otomatis; kolom yang diturunkan dari server akan diprioritaskan jika terjadi konflik."
                      },
                      "paymentMethod": {
                        "type": "object",
                        "description": "Metode pembayaran yang digunakan oleh subjek (dipetakan ke `payment_method`).",
                        "properties": {
                          "type": {
                            "type": "string",
                            "description": "Jenis metode pembayaran (dipetakan ke `method_type`), misalnya `bank_card`, `bank_account`, `crypto_wallet`, `ewallet`, `unhosted_wallet`, `other`."
                          },
                          "accountId": {
                            "type": "string",
                            "description": "Pengidentifikasi akun (memetakan ke `account_id`): IBAN, sidik jari kartu, atau alamat dompet."
                          },
                          "issuingCountry": {
                            "type": "string",
                            "description": "Kode negara ISO 3166-1 alpha-3 dari penerbit (dipetakan ke `issuing_country`)."
                          }
                        }
                      }
                    }
                  },
                  "counterparty": {
                    "type": "object",
                    "description": "Pihak lawan dari transaksi (opsional). Bentuknya sama dengan `subject`; `externalUserId` bermakna di sini.",
                    "properties": {
                      "type": {
                        "type": "string",
                        "description": "Tipe entitas (dipetakan ke `entity_type`): `individual` atau `company`."
                      },
                      "externalUserId": {
                        "type": "string",
                        "description": "Pengenal internal Anda untuk pihak lawan (dipetakan ke `vendor_data`)."
                      },
                      "fullName": {
                        "type": "string"
                      },
                      "firstName": {
                        "type": "string"
                      },
                      "lastName": {
                        "type": "string"
                      },
                      "dob": {
                        "type": "string",
                        "format": "date"
                      },
                      "address": {
                        "type": "object"
                      },
                      "institutionInfo": {
                        "type": "object"
                      },
                      "device": {
                        "type": "object"
                      },
                      "paymentMethod": {
                        "type": "object",
                        "description": "Metode pembayaran yang digunakan oleh pihak lawan (dipetakan ke `payment_method`). Pada transaksi travelRule, `type: \"unhosted_wallet\"` mendeklarasikan dompet pihak lawan sebagai dompet swakelola: transfer melewati perutean VASP pihak lawan, dibuat langsung dalam `UNCONFIRMED_OWNERSHIP`, dan (ketika `auto_wallet_verification` diaktifkan) sesi widget kepemilikan dompet dibuat secara otomatis dan dikembalikan di `action_required` sehingga SDK dapat meluncurkannya.",
                        "properties": {
                          "type": {
                            "type": "string",
                            "description": "Jenis metode pembayaran (dipetakan ke `method_type`), misalnya `bank_card`, `bank_account`, `crypto_wallet`, `ewallet`, `unhosted_wallet`, `other`. Gunakan `unhosted_wallet` untuk mendeklarasikan dompet swakelola untuk Travel Rule."
                          },
                          "accountId": {
                            "type": "string",
                            "description": "Pengidentifikasi akun (memetakan ke `account_id`): IBAN, sidik jari kartu, atau alamat dompet."
                          },
                          "issuingCountry": {
                            "type": "string"
                          }
                        }
                      }
                    }
                  },
                  "props": {
                    "type": "object",
                    "additionalProperties": true,
                    "description": "Pasangan kunci-nilai kustom (memetakan ke `custom_properties`). Setiap kunci dapat direferensikan dalam kondisi aturan sebagai `custom_values.<key>`."
                  },
                  "travelRule": {
                    "type": "object",
                    "description": "Detail Travel Rule (dipetakan ke `travel_rule_details`). Saat Travel Rule diaktifkan untuk aplikasi, Didit mengabaikan `status` apa pun yang Anda kirim dan menjalankan pertukaran itu sendiri.",
                    "required": [
                      "status"
                    ],
                    "properties": {
                      "status": {
                        "type": "string"
                      },
                      "protocol": {
                        "type": "string"
                      },
                      "required": {
                        "type": "boolean"
                      },
                      "obligationsCount": {
                        "type": "integer"
                      },
                      "originatorData": {
                        "type": "object"
                      },
                      "beneficiaryData": {
                        "type": "object"
                      },
                      "metadata": {
                        "type": "object"
                      }
                    }
                  },
                  "includeCryptoScreening": {
                    "type": "boolean",
                    "nullable": true,
                    "description": "Override per transaksi untuk skrining analitik blockchain kripto (memetakan ke `include_crypto_screening`)."
                  },
                  "fingerprint_v2": {
                    "type": "object",
                    "description": "Payload sidik jari perangkat `didit-fp-v2`. Disuntikkan secara otomatis oleh SDK; hanya relevan saat memanggil wire API secara langsung."
                  }
                },
                "required": [
                  "txnId",
                  "type",
                  "info",
                  "subject"
                ]
              },
              "example": {
                "txnId": "wd-2026-07-07-0042",
                "type": "travelRule",
                "info": {
                  "direction": "out",
                  "amount": "0.25",
                  "currency": "ETH",
                  "currencyType": "crypto",
                  "cryptoParams": {
                    "crypto_chain": "ETH"
                  }
                },
                "subject": {
                  "fullName": "Jane Doe"
                },
                "counterparty": {
                  "fullName": "Ana Diaz",
                  "paymentMethod": {
                    "type": "unhosted_wallet",
                    "accountId": "0xBeneficiaryWallet01"
                  }
                },
                "travelRule": {
                  "status": "AWAITING_COUNTERPARTY",
                  "beneficiaryData": {
                    "wallet_address": "0xBeneficiaryWallet01",
                    "name": "Ana Diaz"
                  }
                },
                "includeCryptoScreening": true
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST https://verification.didit.me/v1/transactions/ \\\n  -H 'X-Transaction-Token: SDK_TOKEN' -H 'Content-Type: application/json' \\\n  -d '{\"txnId\": \"wd-2026-07-07-0042\", \"type\": \"travelRule\", \"info\": {\"direction\": \"out\", \"amount\": \"0.25\", \"currency\": \"ETH\", \"currencyType\": \"crypto\"}, \"subject\": {\"fullName\": \"Jane Doe\"}, \"counterparty\": {\"fullName\": \"Ana Diaz\", \"paymentMethod\": {\"type\": \"unhosted_wallet\", \"accountId\": \"0xBeneficiaryWallet01\"}}, \"travelRule\": {\"status\": \"AWAITING_COUNTERPARTY\", \"beneficiaryData\": {\"wallet_address\": \"0xBeneficiaryWallet01\", \"name\": \"Ana Diaz\"}}, \"includeCryptoScreening\": true}'"
          },
          {
            "lang": "javascript",
            "label": "Web SDK",
            "source": "import { DiditSdk } from '@didit-protocol/sdk-web';\n\nconst result = await DiditSdk.shared.submitTransaction({\n  transactionToken: sdkToken,\n  transaction: {\n    txnId: 'wd-2026-07-07-0042',\n    category: 'travelRule',\n    details: { direction: 'out', amount: '0.25', currency: 'ETH', currencyType: 'crypto' },\n    subject: { fullName: 'Jane Doe' },\n    counterparty: { fullName: 'Ana Diaz', paymentMethod: { type: 'unhosted_wallet', accountId: '0xBeneficiaryWallet01' } },\n    travelRule: { status: 'AWAITING_COUNTERPARTY', beneficiaryData: { wallet_address: '0xBeneficiaryWallet01', name: 'Ana Diaz' } },\n    includeCryptoScreening: true\n  },\n  onActionCompleted: (refreshed) => console.log(refreshed.status)\n});"
          }
        ],
        "responses": {
          "201": {
            "description": "Transaksi dikirimkan dan dipantau. Bentuk detail sama dengan `GET /v3/transactions/{transaction_id}/`, termasuk blok `action_required` saat pengguna akhir harus menyelesaikan tindakan lanjutan (SDK meluncurkannya secara otomatis secara default).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TransactionDetail"
                },
                "examples": {
                  "Wallet ownership required": {
                    "value": {
                      "uuid": "22222222-3333-4444-5555-666666666666",
                      "txn_id": "wd-2026-07-07-0042",
                      "transaction_type": "travelRule",
                      "direction": "OUTBOUND",
                      "status": "APPROVED",
                      "amount": "0.25",
                      "currency": "ETH",
                      "travel_rule": {
                        "uuid": "33333333-4444-5555-6666-777777777777",
                        "status": "UNCONFIRMED_OWNERSHIP",
                        "required": true
                      },
                      "action_required": {
                        "type": "wallet_ownership",
                        "url": "https://verify.didit.me/wallet-ownership/3s9x...urlsafe",
                        "widget_session_id": "77777777-8888-9999-aaaa-bbbbbbbbbbbb",
                        "expires_at": "2026-07-07T13:00:00Z"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validasi gagal (kolom wajib tidak ada, duplikasi `txnId`, kategori tidak dikenal).",
            "content": {
              "application/json": {
                "examples": {
                  "Missing fields": {
                    "value": {
                      "transaction_details": {
                        "currency": [
                          "This field is required."
                        ]
                      }
                    }
                  },
                  "Duplicate txnId": {
                    "value": {
                      "transaction_id": [
                        "A transaction with this transaction_id already exists."
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Token transaksi ditolak: hilang, tidak dikenal, dicabut, melebihi `max_uses`, atau kedaluwarsa. Respons token kedaluwarsa selalu memuat kata `expired` dalam detailnya, yang digunakan SDK untuk membedakan kesalahan `expired_token` dari `invalid_token`.",
            "content": {
              "application/json": {
                "examples": {
                  "Invalid token": {
                    "value": {
                      "detail": "Invalid transaction token."
                    }
                  },
                  "Expired token": {
                    "value": {
                      "detail": "Transaction token expired."
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "Permintaan lain dengan `txnId` yang sama membuat transaksi saat permintaan ini sedang diproses, sehingga hanya satu dari dua pengiriman simultan yang berhasil. Baca transaksi yang ada alih-alih mengirim ulang.",
            "content": {
              "application/json": {
                "examples": {
                  "Concurrent duplicate": {
                    "value": {
                      "detail": "A transaction with this transaction_id already exists."
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/transactions/{transaction_id}/": {
      "get": {
        "summary": "Dapatkan transaksi dari SDK",
        "description": "Endpoint baca yang menghadap perangkat, diautentikasi dengan `X-Transaction-Token` yang sama yang digunakan untuk pengiriman. SDK melakukan polling setelah alur tindakan yang diluncurkan otomatis selesai atau jendelanya ditutup, sehingga status akhir tidak pernah bergantung pada satu notifikasi saja. Mengembalikan detail transaksi yang sama dengan respons pengiriman, termasuk blok `action_required` saat ini (`null` setelah tindakan diselesaikan).",
        "operationId": "getTransactionFromSdk",
        "x-didit-sdk": {
          "resource": "transactions",
          "method": "retrieve_from_device",
          "auth": "device_token",
          "server": false
        },
        "tags": [
          "Transactions"
        ],
        "parameters": [
          {
            "name": "transaction_id",
            "in": "path",
            "required": true,
            "description": "UUID transaksi yang stabil dari Didit (`uuid` dari respons submit, **bukan** `txnId` Anda).",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "22222222-3333-4444-5555-666666666666"
          }
        ],
        "security": [
          {
            "TransactionTokenAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v1/transactions/22222222-3333-4444-5555-666666666666/' \\\n  -H 'X-Transaction-Token: SDK_TOKEN'"
          }
        ],
        "responses": {
          "200": {
            "description": "Detail transaksi lengkap, termasuk `action_required` (`null` setelah tindakan yang tertunda diselesaikan).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TransactionDetail"
                }
              }
            }
          },
          "401": {
            "description": "Token transaksi ditolak: hilang, tidak dikenal, dicabut, melebihi `max_uses`, atau kedaluwarsa.",
            "content": {
              "application/json": {
                "examples": {
                  "Expired token": {
                    "value": {
                      "detail": "Transaction token expired."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Tidak ada transaksi dengan UUID ini untuk aplikasi yang terkait dengan token tersebut, atau segmen path bukan UUID yang valid.",
            "content": {
              "application/json": {
                "examples": {
                  "Not found": {
                    "value": {
                      "detail": "Not found."
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v3/businesses/": {
      "get": {
        "summary": "Daftar bisnis",
        "description": "Daftar [bisnis](/entities/businesses) yang dikumpulkan Didit dari sesi KYB yang berbagi `vendor_data` yang sama (string format bebas, BUKAN UUID), beserta bisnis yang dibuat melalui API. Dipaginasi, diurutkan berdasarkan `last_session_at` menurun. Endpoint ini tidak mendukung parameter pemfilteran atau pencarian — ambil halaman dan filter di sisi klien.",
        "operationId": "list_businesses",
        "x-didit-sdk": {
          "resource": "businesses",
          "method": "list",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Businesses"
        ],
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 50,
              "minimum": 1,
              "maximum": 1000000
            },
            "description": "Ukuran halaman. Nilai default-nya 50 jika dihilangkan. Tidak ada batasan maksimum yang diterapkan, tetapi jaga ukuran halaman tetap kecil demi latensi."
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 0,
              "minimum": 0,
              "maximum": 1000000
            },
            "description": "Offset berbasis nol dari rekaman pertama yang dikembalikan. Sebaiknya ikuti URL `next` dari halaman sebelumnya daripada menghitungnya secara manual."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/businesses/?limit=50' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nfor item in client.businesses.list():\n    print(item)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nfor await (const item of didit.businesses.list()) {\n  console.log(item);\n}"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\niter := client.Businesses.ListAutoPaging(ctx, didit.BusinessesListParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nfor (var item : client.businesses().list()) {\n    System.out.println(item);\n}"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\nforeach ($didit->businesses->list() as $item) {\n    print_r($item->toArray());\n}"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.businesses.list.auto_paging_each do |item|\n  puts item.to_h\nend"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.Businesses.ListAsync())\n{\n    Console.WriteLine(JsonSerializer.Serialize(item));\n}"
          }
        ],
        "responses": {
          "200": {
            "description": "Daftar bisnis berpaginasi dengan status, jumlah sesi, dan rincian fitur.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "count": {
                      "type": "integer",
                      "description": "Jumlah baris yang cocok — tepat hingga 100, dibatasi pada 100 setelahnya demi performa. Jangan gunakan ini untuk mendeteksi halaman terakhir; andalkan `next` yang bernilai `null` sebagai gantinya."
                    },
                    "next": {
                      "type": "string",
                      "nullable": true,
                      "description": "URL absolut halaman berikutnya, atau `null` di halaman terakhir."
                    },
                    "previous": {
                      "type": "string",
                      "nullable": true,
                      "description": "URL absolut halaman sebelumnya, atau `null` di halaman pertama."
                    },
                    "results": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/BusinessListItem"
                      }
                    }
                  }
                },
                "examples": {
                  "Example": {
                    "value": {
                      "count": 1,
                      "next": null,
                      "previous": null,
                      "results": [
                        {
                          "didit_internal_id": "a1b2c3d4-e5f6-4890-abcd-ef1234567890",
                          "vendor_data": "company-123",
                          "display_name": null,
                          "legal_name": "Acme Trading Ltd",
                          "registration_number": "12345678",
                          "country_code": "GB",
                          "effective_name": "Acme Trading Ltd",
                          "status": "ACTIVE",
                          "session_count": 2,
                          "approved_count": 1,
                          "declined_count": 0,
                          "in_review_count": 1,
                          "features": {
                            "KYB": "Approved"
                          },
                          "features_list": [
                            {
                              "feature": "KYB",
                              "status": "Approved"
                            }
                          ],
                          "last_session_at": "2026-03-15T10:30:00Z",
                          "last_activity_at": "2026-03-15T10:30:00Z",
                          "first_session_at": "2026-01-10T08:00:00Z",
                          "tags": [
                            {
                              "uuid": "9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d",
                              "name": "VIP",
                              "color": "#2567FF"
                            }
                          ],
                          "created_at": "2026-01-10T08:00:00Z"
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Kunci API tidak ada, tidak valid, atau dicabut, atau kunci tersebut tidak dapat menampilkan daftar bisnis untuk aplikasi ini. Kunci yang tidak ada mengembalikan `403`; kunci yang salah, dicabut, atau kedaluwarsa mengembalikan `401`.",
            "content": {
              "application/json": {
                "examples": {
                  "Forbidden": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Batas laju terlampaui; kurangi laju permintaan dan coba lagi setelah interval yang ditunjukkan dalam `Retry-After`.",
            "content": {
              "application/json": {
                "examples": {
                  "Rate limited": {
                    "value": {
                      "detail": "Request was throttled. Expected available in 30 seconds."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/customization/": {
      "get": {
        "summary": "Dapatkan kustomisasi branding",
        "description": "Mengembalikan branding White Label untuk aplikasi yang ditentukan berdasarkan kunci API: warna, font, border radius, URL logo, dan opsi UI/UX. Pengaturan domain kustom dan email White Label hanya dikelola di Business Console dan bukan merupakan bagian dari respons ini.",
        "operationId": "get_customization",
        "x-didit-sdk": {
          "resource": "customization",
          "method": "retrieve",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Customization"
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/customization/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.customization.retrieve()\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.customization.retrieve();\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Customization.Retrieve(ctx)\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.customization().retrieve();\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->customization->retrieve();\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.customization.retrieve\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Customization.RetrieveAsync();\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "Kustomisasi merek saat ini untuk aplikasi.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BrandingCustomization"
                },
                "examples": {
                  "Default branding": {
                    "value": {
                      "color_primary": "#000000",
                      "color_secondary": "#9DA1A1",
                      "color_background": "#FFFFFF",
                      "color_panel": "#2567FF",
                      "color_panel_10": "#1A1A1A",
                      "color_on_panel_1": "#9DA1A1",
                      "color_on_panel_2": "#F4F4F6",
                      "color_on_background": "#000000",
                      "color_button_1": "#2567FF",
                      "color_button_2": "#F8F8F8",
                      "color_button_text_1": "#FFFFFF",
                      "color_button_text_2": "#000000",
                      "color_pill_text": "#111827",
                      "border_radius_panel": 10,
                      "border_radius_buttons": 12,
                      "font_family": "Inter",
                      "font_weight": "regular",
                      "font_url": "https://fonts.googleapis.com/css2?family=Inter",
                      "logo_square": null,
                      "logo_rectangular": null,
                      "logo_rectangular_dark": null,
                      "favicon": null,
                      "app_public_name": "Acme Verify",
                      "privacy_policy_url": "https://acme.com/privacy",
                      "skip_welcome_screen": false,
                      "disable_login_with_didit": false,
                      "hide_progress_bar": false,
                      "callback_seconds": 3
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Kunci API tidak ada, format salah, kedaluwarsa, atau memiliki cakupan untuk aplikasi yang berbeda. Kunci yang tidak ada mengembalikan `403`; kunci yang salah, dicabut, atau kedaluwarsa mengembalikan `401`.",
            "content": {
              "application/json": {
                "examples": {
                  "Invalid token": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Batas laju terlampaui. Coba lagi dengan backoff eksponensial."
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      },
      "patch": {
        "summary": "Perbarui kustomisasi branding",
        "description": "Pembaruan parsial untuk branding White Label aplikasi. Kirim `application/json` untuk mengubah warna, font, radius, dan opsi UI, atau `multipart/form-data` untuk mengunggah gambar logo. Hanya kolom yang Anda sertakan yang akan diubah. Domain kustom dan email White Label tidak dapat diatur melalui endpoint ini — gunakan Business Console untuk pengaturan tersebut.",
        "operationId": "update_customization",
        "x-didit-sdk": {
          "resource": "customization",
          "method": "update",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Customization"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BrandingCustomizationUpdate"
              },
              "examples": {
                "Update colors and font": {
                  "summary": "Ubah font dan warna branding",
                  "value": {
                    "color_primary": "#123456",
                    "color_button_1": "#2567FF",
                    "font_family": "AR One Sans",
                    "border_radius_buttons": 16
                  }
                },
                "Update UI options": {
                  "summary": "Ubah nama publik dan opsi alur",
                  "value": {
                    "app_public_name": "Acme Verify",
                    "privacy_policy_url": "https://acme.com/privacy",
                    "skip_welcome_screen": true,
                    "hide_progress_bar": true,
                    "callback_seconds": 5
                  }
                },
                "Remove a logo": {
                  "summary": "Hapus logo persegi panjang saat ini",
                  "value": {
                    "delete_logo_rectangular": true
                  }
                },
                "Remove the dark-mode logo": {
                  "summary": "Hapus logo mode gelap saat ini",
                  "value": {
                    "delete_logo_rectangular_dark": true
                  }
                }
              }
            },
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "description": "Gunakan multipart/form-data hanya untuk mengunggah gambar logo. Kolom branding di atas juga dapat dikirim sebagai kolom form dalam permintaan yang sama.",
                "properties": {
                  "image_square": {
                    "type": "string",
                    "format": "binary",
                    "description": "Logo persegi (rasio aspek 1:1). PNG, JPG, atau WebP, setidaknya 512 px pada sisi panjang, maksimal **1 MB**."
                  },
                  "image_rectangular": {
                    "type": "string",
                    "format": "binary",
                    "description": "Logo persegi panjang (rasio aspek 2:1). PNG, JPG, atau WebP, minimal 512 px pada sisi panjang, maksimal **1 MB**."
                  },
                  "image_rectangular_dark": {
                    "type": "string",
                    "format": "binary",
                    "description": "Logo persegi panjang untuk mode gelap (rasio aspek 2:1), ditampilkan pada latar belakang gelap. PNG, JPG, atau WebP, minimal 512 px pada sisi panjang, maksimal **1 MB**. Dikembalikan sebagai `logo_rectangular_dark`."
                  },
                  "image_favicon": {
                    "type": "string",
                    "format": "binary",
                    "description": "Gambar favicon. Maks **500 KB**."
                  }
                }
              },
              "example": {
                "image_rectangular": "(binary PNG logo, 2:1)",
                "image_rectangular_dark": "(binary PNG logo for dark mode, 2:1)",
                "image_favicon": "(binary favicon)"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X PATCH 'https://verification.didit.me/v3/customization/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"color_primary\": \"#123456\", \"font_family\": \"AR One Sans\"}'"
          },
          {
            "lang": "curl",
            "label": "curl (logo upload)",
            "source": "curl -X PATCH 'https://verification.didit.me/v3/customization/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -F 'image_rectangular=@logo.png' \\\n  -F 'image_rectangular_dark=@logo-dark.png' \\\n  -F 'image_favicon=@favicon.ico'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.customization.update(\n    image_rectangular=open(\"image_rectangular.jpg\", \"rb\"),\n    image_rectangular_dark=open(\"image_rectangular_dark.jpg\", \"rb\"),\n    image_favicon=open(\"image_favicon.jpg\", \"rb\"),\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit, { fileFromPath } from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.customization.update({\n  image_rectangular: await fileFromPath(\"image_rectangular.jpg\"),\n  image_rectangular_dark: await fileFromPath(\"image_rectangular_dark.jpg\"),\n  image_favicon: await fileFromPath(\"image_favicon.jpg\"),\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Customization.Update(ctx, didit.CustomizationUpdateParams{\n\tImageRectangular:     didit.Some(didit.FileFromPath(\"image_rectangular.jpg\")),\n\tImageRectangularDark: didit.Some(didit.FileFromPath(\"image_rectangular_dark.jpg\")),\n\tImageFavicon:         didit.Some(didit.FileFromPath(\"image_favicon.jpg\")),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.nio.file.Path;\nimport me.didit.Didit;\nimport me.didit.types.CustomizationUpdateParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.customization().update(CustomizationUpdateParams.builder()\n        .imageRectangular(Path.of(\"image_rectangular.jpg\"))\n        .imageRectangularDark(Path.of(\"image_rectangular_dark.jpg\"))\n        .imageFavicon(Path.of(\"image_favicon.jpg\"))\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\nuse Didit\\File;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->customization->update([\n    'image_rectangular' => File::fromPath('image_rectangular.jpg'),\n    'image_rectangular_dark' => File::fromPath('image_rectangular_dark.jpg'),\n    'image_favicon' => File::fromPath('image_favicon.jpg'),\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.customization.update(\n  image_rectangular: Pathname(\"image_rectangular.jpg\"),\n  image_rectangular_dark: Pathname(\"image_rectangular_dark.jpg\"),\n  image_favicon: Pathname(\"image_favicon.jpg\")\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Customization.UpdateAsync(new CustomizationUpdateParams\n{\n    ImageRectangular = FileUpload.FromPath(\"image_rectangular.jpg\"),\n    ImageRectangularDark = FileUpload.FromPath(\"image_rectangular_dark.jpg\"),\n    ImageFavicon = FileUpload.FromPath(\"image_favicon.jpg\"),\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "Branding diperbarui. Objek branding LENGKAP akan dikembalikan (semua kolom, bukan hanya yang Anda ubah).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BrandingCustomization"
                },
                "examples": {
                  "Updated": {
                    "value": {
                      "color_primary": "#123456",
                      "color_secondary": "#9DA1A1",
                      "color_background": "#FFFFFF",
                      "color_panel": "#2567FF",
                      "color_panel_10": "#1A1A1A",
                      "color_on_panel_1": "#9DA1A1",
                      "color_on_panel_2": "#F4F4F6",
                      "color_on_background": "#000000",
                      "color_button_1": "#2567FF",
                      "color_button_2": "#F8F8F8",
                      "color_button_text_1": "#FFFFFF",
                      "color_button_text_2": "#000000",
                      "color_pill_text": "#111827",
                      "border_radius_panel": 10,
                      "border_radius_buttons": 16,
                      "font_family": "AR One Sans",
                      "font_weight": "400",
                      "font_url": "https://fonts.googleapis.com/css2?family=AR+One+Sans",
                      "logo_square": null,
                      "logo_rectangular": "https://cdn.didit.me/white_label/logo_rectangular/...",
                      "logo_rectangular_dark": null,
                      "favicon": null,
                      "app_public_name": "Acme Verify",
                      "privacy_policy_url": "https://acme.com/privacy",
                      "skip_welcome_screen": true,
                      "disable_login_with_didit": false,
                      "hide_progress_bar": false,
                      "callback_seconds": 3
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Body tidak valid. Sebagai contoh: warna heksadesimal yang salah format, keluarga font atau ketebalan font yang tidak dikenal, kolom khusus Business Console (`domain`, `from_email`, `verify_domain`, `force_remove_domain`, `verify_email_domain`, `force_remove_email_domain`, dan pasangan hanya-baca miliknya), atau unggahan logo yang bukan gambar PNG, JPG, atau WebP, berukuran di bawah 512 px pada sisi panjangnya, lebih dari 1 MB, atau memiliki rasio aspek yang salah. Juga dikembalikan saat menyetel `disable_login_with_didit` ke `false` saat domain kustom dikonfigurasi.",
            "content": {
              "application/json": {
                "examples": {
                  "Bad color": {
                    "value": {
                      "color_primary": [
                        "Invalid color format. Use '#RRGGBB' or '#RRGGBBAA' format."
                      ]
                    }
                  },
                  "Bad logo": {
                    "value": {
                      "image_rectangular": [
                        "Image aspect ratio must be 2:1. Got 1024x1024 image dimensions"
                      ]
                    }
                  },
                  "Unsupported logo format": {
                    "summary": "Bukan gambar PNG, JPG, atau WebP (misalnya SVG)",
                    "value": {
                      "image_rectangular_dark": [
                        "Upload a PNG, JPG or WebP image."
                      ]
                    }
                  },
                  "Logo too small": {
                    "summary": "Di bawah 512 px pada sisi panjang",
                    "value": {
                      "image_rectangular": [
                        "Image must be at least 512 px on its long side. Got 400x200 image dimensions"
                      ]
                    }
                  },
                  "Logo too large": {
                    "summary": "Lebih dari 1 MB",
                    "value": {
                      "image_square": [
                        "File size should not exceed 1 MB"
                      ]
                    }
                  },
                  "Console-only field": {
                    "value": {
                      "domain": [
                        "Manage this field in the Business Console."
                      ]
                    }
                  },
                  "Bad font weight": {
                    "value": {
                      "font_weight": [
                        "Font weight 950 is not available for Inter. Available weights are: 100, 200, 300, 400, 500, 600, 700, 800, 900"
                      ]
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Kunci API tidak ada, format salah, kedaluwarsa, atau memiliki cakupan untuk aplikasi yang berbeda. Kunci yang tidak ada mengembalikan `403`; kunci yang salah, dicabut, atau kedaluwarsa mengembalikan `401`.",
            "content": {
              "application/json": {
                "examples": {
                  "Invalid token": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Batas laju terlampaui. Coba lagi dengan backoff eksponensial."
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/businesses/{vendor_data}/": {
      "get": {
        "summary": "Dapatkan bisnis",
        "description": "Ambil satu [bisnis](/entities/businesses) berdasarkan `vendor_data` (kecocokan persis). Menambahkan `metadata` dan `updated_at` ke tampilan daftar. Bisnis yang dihapus mengembalikan 404.",
        "operationId": "get_business",
        "x-didit-sdk": {
          "resource": "businesses",
          "method": "retrieve",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Businesses"
        ],
        "parameters": [
          {
            "name": "vendor_data",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Pengidentifikasi unik Anda untuk bisnis — string bentuk bebas (BUKAN UUID), dicocokkan persis seperti yang dikirim.",
            "example": "company-123"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/businesses/company-123/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.businesses.retrieve(\n    \"company-123\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.businesses.retrieve(\"company-123\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Businesses.Retrieve(ctx, \"company-123\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.businesses().retrieve(\"company-123\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->businesses->retrieve('company-123');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.businesses.retrieve(\"company-123\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Businesses.RetrieveAsync(\"company-123\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "Detail lengkap bisnis termasuk metadata dan agregasi data sesi.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BusinessDetailItem"
                },
                "examples": {
                  "Active business": {
                    "value": {
                      "didit_internal_id": "a1b2c3d4-e5f6-4890-abcd-ef1234567890",
                      "vendor_data": "company-123",
                      "display_name": null,
                      "legal_name": "Acme Trading Ltd",
                      "registration_number": "12345678",
                      "country_code": "GB",
                      "effective_name": "Acme Trading Ltd",
                      "status": "ACTIVE",
                      "session_count": 2,
                      "approved_count": 1,
                      "declined_count": 0,
                      "in_review_count": 1,
                      "features": {
                        "KYB": "Approved"
                      },
                      "features_list": [
                        {
                          "feature": "KYB",
                          "status": "Approved"
                        }
                      ],
                      "last_session_at": "2026-03-15T10:30:00Z",
                      "last_activity_at": "2026-03-15T10:30:00Z",
                      "first_session_at": "2026-01-10T08:00:00Z",
                      "tags": [
                        {
                          "uuid": "9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d",
                          "name": "VIP",
                          "color": "#2567FF"
                        }
                      ],
                      "created_at": "2026-01-10T08:00:00Z",
                      "metadata": {
                        "industry": "fintech"
                      },
                      "updated_at": "2026-03-15T10:30:00Z"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Kunci API tidak ada, tidak valid, atau dicabut, atau kunci tersebut tidak dapat membaca bisnis aplikasi ini. Kunci yang tidak ada mengembalikan `403`; kunci yang salah, dicabut, atau kedaluwarsa mengembalikan `401`.",
            "content": {
              "application/json": {
                "examples": {
                  "Forbidden": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Tidak ada bisnis (yang belum dihapus) dengan `vendor_data` yang diberikan untuk aplikasi ini.",
            "content": {
              "application/json": {
                "examples": {
                  "Not found": {
                    "value": {
                      "detail": "Not found."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Batas laju terlampaui; kurangi laju permintaan dan coba lagi setelah interval yang ditunjukkan dalam `Retry-After`.",
            "content": {
              "application/json": {
                "examples": {
                  "Rate limited": {
                    "value": {
                      "detail": "Request was throttled. Expected available in 30 seconds."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      },
      "patch": {
        "summary": "Perbarui bisnis",
        "description": "Pembaruan parsial untuk bisnis: `display_name`, `legal_name`, `registration_number`, `country_code`, `status`, `metadata`. `metadata` menggantikan sepenuhnya. Mengatur `status` ke `BLOCKED` akan menambahkan `vendor_data` ke daftar blokir sistem; mengubahnya dari `BLOCKED` akan menghapus entri tersebut. Setiap pengeditan dicatat dalam aktivitas perusahaan: perubahan status dengan `reason` opsional, dan perubahan pada `display_name`, `legal_name`, `registration_number`, `country_code`, atau `metadata` sebagai pembaruan profil.",
        "operationId": "update_business",
        "x-didit-sdk": {
          "resource": "businesses",
          "method": "update",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Businesses"
        ],
        "parameters": [
          {
            "name": "vendor_data",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Pengidentifikasi unik Anda untuk bisnis (string bentuk bebas, BUKAN UUID).",
            "example": "company-123"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "description": "Body pembaruan parsial. Berikan hanya kolom yang ingin Anda ubah.",
                "properties": {
                  "display_name": {
                    "type": "string",
                    "nullable": true,
                    "description": "Nama tampilan yang mudah dipahami yang ditampilkan di konsol (mengambil prioritas di atas `legal_name` untuk tampilan antarmuka)."
                  },
                  "legal_name": {
                    "type": "string",
                    "nullable": true,
                    "description": "Nama resmi menurut hukum dari registri atau entri manual."
                  },
                  "registration_number": {
                    "type": "string",
                    "nullable": true,
                    "description": "Nomor registrasi atau nomor pendirian perusahaan."
                  },
                  "country_code": {
                    "type": "string",
                    "nullable": true,
                    "description": "Negara pendirian (ISO 3166-1 alpha-2, misalnya `GB`, `US`)."
                  },
                  "status": {
                    "type": "string",
                    "enum": [
                      "ACTIVE",
                      "FLAGGED",
                      "BLOCKED"
                    ],
                    "description": "Status siklus hidup bisnis. Menyetel `BLOCKED` secara otomatis menambahkan `vendor_data` ke daftar blokir sistem; beralih dari `BLOCKED` menghapus entri daftar blokir tersebut."
                  },
                  "metadata": {
                    "type": "object",
                    "nullable": true,
                    "description": "Objek JSON arbitrer yang Anda lampirkan ke bisnis. **Menggantikan sepenuhnya** metadata yang ada saat pembaruan — gabungkan di sisi klien jika Anda hanya ingin menambahkan kunci."
                  },
                  "reason": {
                    "type": "string",
                    "nullable": true,
                    "maxLength": 1000,
                    "description": "Alasan mengapa status berubah. Dicatat pada entri perubahan status di **Activity** perusahaan di Business Console, hanya jika status benar-benar berubah. Webhook tidak menyertakannya."
                  }
                }
              },
              "examples": {
                "Update name": {
                  "summary": "Perbarui nama tampilan",
                  "value": {
                    "display_name": "Acme Corp"
                  }
                },
                "Flag for review": {
                  "summary": "Ubah status",
                  "value": {
                    "status": "FLAGGED"
                  }
                },
                "Add metadata": {
                  "summary": "Ganti JSON metadata",
                  "value": {
                    "metadata": {
                      "industry": "fintech",
                      "risk_level": "low"
                    }
                  }
                },
                "Fix registry data": {
                  "summary": "Koreksi kolom yang diekstrak",
                  "value": {
                    "legal_name": "Acme Trading International Ltd",
                    "registration_number": "12345678",
                    "country_code": "GB"
                  }
                },
                "Flag with reason": {
                  "summary": "Tandai bisnis dan catat alasannya",
                  "value": {
                    "status": "FLAGGED",
                    "reason": "Ownership structure under review"
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X PATCH 'https://verification.didit.me/v3/businesses/company-123/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"display_name\": \"Acme Corp\", \"status\": \"FLAGGED\"}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.businesses.update(\n    \"company-123\",\n    display_name=\"Acme Corp\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.businesses.update(\"company-123\", {\n  display_name: \"Acme Corp\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Businesses.Update(ctx, \"company-123\", didit.BusinessesUpdateParams{\n\tDisplayName: didit.String(\"Acme Corp\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.BusinessesUpdateParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.businesses().update(\"company-123\", BusinessesUpdateParams.builder()\n        .displayName(\"Acme Corp\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->businesses->update('company-123', [\n    'display_name' => 'Acme Corp',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.businesses.update(\n  \"company-123\",\n  display_name: \"Acme Corp\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Businesses.UpdateAsync(\"company-123\", new BusinessesUpdateParams\n{\n    DisplayName = \"Acme Corp\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "Bisnis diperbarui. Data bisnis lengkap yang telah diperbarui dikembalikan.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BusinessDetailItem"
                },
                "examples": {
                  "Updated": {
                    "value": {
                      "didit_internal_id": "a1b2c3d4-e5f6-4890-abcd-ef1234567890",
                      "vendor_data": "company-123",
                      "display_name": "Acme Corp",
                      "legal_name": "Acme Trading Ltd",
                      "registration_number": "12345678",
                      "country_code": "GB",
                      "effective_name": "Acme Corp",
                      "status": "FLAGGED",
                      "session_count": 2,
                      "approved_count": 1,
                      "declined_count": 0,
                      "in_review_count": 1,
                      "features": {
                        "KYB": "Approved"
                      },
                      "features_list": [
                        {
                          "feature": "KYB",
                          "status": "Approved"
                        }
                      ],
                      "last_session_at": "2026-03-15T10:30:00Z",
                      "last_activity_at": "2026-03-15T10:30:00Z",
                      "first_session_at": "2026-01-10T08:00:00Z",
                      "tags": [
                        {
                          "uuid": "9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d",
                          "name": "VIP",
                          "color": "#2567FF"
                        }
                      ],
                      "created_at": "2026-01-10T08:00:00Z",
                      "metadata": {
                        "industry": "fintech",
                        "risk_level": "low"
                      },
                      "updated_at": "2026-03-15T10:30:00Z"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Body tidak valid: biasanya `status` yang tidak dikenal, `metadata` yang salah format, atau `reason` lebih dari 1000 karakter.",
            "content": {
              "application/json": {
                "examples": {
                  "Bad status": {
                    "value": {
                      "status": [
                        "Invalid status. Valid options are: ACTIVE, FLAGGED, BLOCKED"
                      ]
                    }
                  },
                  "Bad metadata": {
                    "value": {
                      "metadata": [
                        "Metadata must be a JSON object."
                      ]
                    }
                  },
                  "Reason too long": {
                    "value": {
                      "reason": [
                        "Ensure this field has no more than 1000 characters."
                      ]
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Kunci API tidak ada, tidak valid, atau dicabut, atau kunci tersebut tidak dapat memperbarui bisnis untuk aplikasi ini. Kunci yang tidak ada mengembalikan `403`; kunci yang salah, dicabut, atau kedaluwarsa mengembalikan `401`.",
            "content": {
              "application/json": {
                "examples": {
                  "Forbidden": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Tidak ada bisnis (yang belum dihapus) dengan `vendor_data` yang diberikan untuk aplikasi ini.",
            "content": {
              "application/json": {
                "examples": {
                  "Not found": {
                    "value": {
                      "detail": "Not found."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Batas laju terlampaui; kurangi laju permintaan dan coba lagi setelah interval yang ditunjukkan dalam `Retry-After`.",
            "content": {
              "application/json": {
                "examples": {
                  "Rate limited": {
                    "value": {
                      "detail": "Request was throttled. Expected available in 30 seconds."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/businesses/{vendor_data}/update-status/": {
      "patch": {
        "summary": "Perbarui status bisnis",
        "description": "Ubah hanya `status` siklus hidup bisnis: `ACTIVE`, `FLAGGED`, atau `BLOCKED` (bukan status sesi). `BLOCKED` menambahkan `vendor_data` ke daftar blokir sistem; berpindah dari `BLOCKED` akan menghapus entri tersebut. Setiap perubahan dicatat dalam aktivitas perusahaan, beserta `reason` opsional. Mengirim status saat ini tidak mengubah apa pun dan tidak mencatat `reason`. Webhook `business.status.updated` tidak memuat `reason`.",
        "operationId": "update_business_status",
        "x-didit-sdk": {
          "resource": "businesses",
          "method": "update_status",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Businesses"
        ],
        "parameters": [
          {
            "name": "vendor_data",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Pengidentifikasi unik Anda untuk bisnis (string bentuk bebas, BUKAN UUID).",
            "example": "company-123"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "allOf": [
                  {
                    "$ref": "#/components/schemas/EntityStatusUpdateRequest"
                  },
                  {
                    "type": "object",
                    "properties": {
                      "reason": {
                        "type": "string",
                        "nullable": true,
                        "maxLength": 1000,
                        "description": "Alasan mengapa status berubah. Dicatat pada entri perubahan status di **Activity** perusahaan di Business Console, hanya jika status benar-benar berubah. Webhook tidak menyertakannya."
                      }
                    }
                  }
                ]
              },
              "examples": {
                "Flag": {
                  "summary": "Tandai bisnis untuk ditinjau",
                  "value": {
                    "status": "FLAGGED"
                  }
                },
                "Block": {
                  "summary": "Blokir bisnis (menambahkan ke daftar blokir sistem)",
                  "value": {
                    "status": "BLOCKED"
                  }
                },
                "Reactivate": {
                  "summary": "Aktifkan kembali bisnis",
                  "value": {
                    "status": "ACTIVE"
                  }
                },
                "Block with reason": {
                  "summary": "Blokir bisnis dan catat alasannya",
                  "value": {
                    "status": "BLOCKED",
                    "reason": "Registry shows the company dissolved"
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X PATCH 'https://verification.didit.me/v3/businesses/company-123/update-status/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"status\": \"BLOCKED\"}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.businesses.update_status(\n    \"company-123\",\n    status=\"FLAGGED\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.businesses.updateStatus(\"company-123\", {\n  status: \"FLAGGED\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Businesses.UpdateStatus(ctx, \"company-123\", didit.BusinessesUpdateStatusParams{\n\tStatus: \"FLAGGED\",\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.BusinessesUpdateStatusParams;\nimport me.didit.types.EntityStatusUpdateRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.businesses().updateStatus(\"company-123\", BusinessesUpdateStatusParams.builder()\n        .status(EntityStatusUpdateRequest.Status.of(\"FLAGGED\"))\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->businesses->updateStatus('company-123', [\n    'status' => 'FLAGGED',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.businesses.update_status(\n  \"company-123\",\n  status: \"FLAGGED\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Businesses.UpdateStatusAsync(\"company-123\", new BusinessesUpdateStatusParams\n{\n    Status = \"FLAGGED\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "Status bisnis diperbarui. Data bisnis lengkap dikembalikan.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BusinessDetailItem"
                },
                "examples": {
                  "Blocked": {
                    "value": {
                      "didit_internal_id": "a1b2c3d4-e5f6-4890-abcd-ef1234567890",
                      "vendor_data": "company-123",
                      "display_name": null,
                      "legal_name": "Acme Trading Ltd",
                      "registration_number": "12345678",
                      "country_code": "GB",
                      "effective_name": "Acme Trading Ltd",
                      "status": "BLOCKED",
                      "session_count": 2,
                      "approved_count": 1,
                      "declined_count": 0,
                      "in_review_count": 1,
                      "features": {
                        "KYB": "Approved"
                      },
                      "features_list": [
                        {
                          "feature": "KYB",
                          "status": "Approved"
                        }
                      ],
                      "last_session_at": "2026-03-15T10:30:00Z",
                      "last_activity_at": "2026-03-15T10:30:00Z",
                      "first_session_at": "2026-01-10T08:00:00Z",
                      "tags": [
                        {
                          "uuid": "9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d",
                          "name": "VIP",
                          "color": "#2567FF"
                        }
                      ],
                      "created_at": "2026-01-10T08:00:00Z",
                      "metadata": {
                        "industry": "fintech"
                      },
                      "updated_at": "2026-03-15T10:30:00Z"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "`status` tidak ada atau tidak valid, atau `reason` lebih dari 1000 karakter.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing status": {
                    "value": {
                      "status": [
                        "This field is required."
                      ]
                    }
                  },
                  "Bad status": {
                    "value": {
                      "status": [
                        "Invalid status. Valid options are: ACTIVE, FLAGGED, BLOCKED"
                      ]
                    }
                  },
                  "Reason too long": {
                    "value": {
                      "reason": [
                        "Ensure this field has no more than 1000 characters."
                      ]
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Kunci API tidak ada, tidak valid, atau dicabut, atau kunci tersebut tidak dapat memperbarui bisnis untuk aplikasi ini. Kunci yang tidak ada mengembalikan `403`; kunci yang salah, dicabut, atau kedaluwarsa mengembalikan `401`.",
            "content": {
              "application/json": {
                "examples": {
                  "Forbidden": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Tidak ada bisnis (yang belum dihapus) dengan `vendor_data` yang diberikan untuk aplikasi ini.",
            "content": {
              "application/json": {
                "examples": {
                  "Not found": {
                    "value": {
                      "detail": "Not found."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Batas laju terlampaui; kurangi laju permintaan dan coba lagi setelah interval yang ditunjukkan dalam `Retry-After`.",
            "content": {
              "application/json": {
                "examples": {
                  "Rate limited": {
                    "value": {
                      "detail": "Request was throttled. Expected available in 30 seconds."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/businesses/delete/": {
      "post": {
        "summary": "Hapus bisnis secara batch",
        "description": "**Hapus bisnis secara permanen** — tindakan ini tidak dapat dibatalkan. Untuk pemblokiran, lebih disarankan menggunakan [Perbarui Status Bisnis](#patch-/v3/businesses/-vendor_data-/update-status/) dengan `BLOCKED`.\n\n**Laporan regulasi yang telah diajukan:** jika data yang dipilih berada dalam laporan regulasi yang sudah final, seluruh permintaan akan ditolak dengan `409` dan tidak ada yang dihapus. Isi respons menggunakan `code: in_filed_report` dan menyebutkan setiap laporan beserta `uuid`, `report_number`, `report_type`, dan `case_uuid`. Hapus laporan tersebut, lalu ulangi permintaan.",
        "operationId": "batch_delete_businesses",
        "x-didit-sdk": {
          "resource": "businesses",
          "method": "batch_delete",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Businesses"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "description": "Sediakan `vendor_data_list`, `didit_internal_id_list`, atau `delete_all: true`. Prioritas ketika beberapa dikirimkan: `delete_all` > `vendor_data_list` > `didit_internal_id_list` (hanya selektor dengan prioritas tertinggi yang digunakan).",
                "properties": {
                  "vendor_data_list": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Pengenal Anda sendiri yang akan dihapus, dicocokkan persis seperti yang dikirimkan."
                  },
                  "didit_internal_id_list": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "description": "UUID internal Didit (`didit_internal_id`) yang akan dihapus."
                  },
                  "delete_all": {
                    "type": "boolean",
                    "default": false,
                    "description": "Jika `true`, menghapus setiap bisnis di aplikasi. Tidak dapat digabungkan dengan pemilih daftar."
                  }
                }
              },
              "examples": {
                "Specific businesses": {
                  "summary": "Hapus berdasarkan vendor_data",
                  "value": {
                    "vendor_data_list": [
                      "company-123",
                      "company-456"
                    ]
                  }
                },
                "Specific internal IDs": {
                  "summary": "Hapus berdasarkan didit_internal_id",
                  "value": {
                    "didit_internal_id_list": [
                      "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
                      "b2c3d4e5-f6a7-8901-bcde-f12345678901"
                    ]
                  }
                },
                "All businesses": {
                  "summary": "Hapus semua bisnis dalam aplikasi ini",
                  "value": {
                    "delete_all": true
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://verification.didit.me/v3/businesses/delete/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"vendor_data_list\": [\"company-123\", \"company-456\"]}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.businesses.batch_delete(\n    vendor_data_list=[\"company-123\", \"company-456\"],\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.businesses.batchDelete({\n  vendor_data_list: [\"company-123\", \"company-456\"],\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Businesses.BatchDelete(ctx, didit.BusinessesBatchDeleteParams{\n\tVendorDataList: didit.Some([]string{\"company-123\", \"company-456\"}),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.List;\nimport me.didit.Didit;\nimport me.didit.types.BusinessesBatchDeleteParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.businesses().batchDelete(BusinessesBatchDeleteParams.builder()\n        .vendorDataList(List.of(\"company-123\", \"company-456\"))\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->businesses->batchDelete([\n    'vendor_data_list' => ['company-123', 'company-456'],\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.businesses.batch_delete(vendor_data_list: [\"company-123\", \"company-456\"])\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Businesses.BatchDeleteAsync(new BusinessesBatchDeleteParams\n{\n    VendorDataList = new string[] { \"company-123\", \"company-456\" },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "Bisnis dihapus. Mengembalikan jumlah baris yang benar-benar dihapus.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "deleted": {
                      "type": "integer",
                      "description": "Jumlah bisnis yang dihapus (tidak termasuk nilai vendor_data yang tidak cocok dengan apa pun)."
                    }
                  }
                },
                "examples": {
                  "Deleted some": {
                    "value": {
                      "deleted": 2
                    }
                  },
                  "Nothing matched": {
                    "value": {
                      "deleted": 0
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Tidak ada selektor yang diberikan (semua `vendor_data_list`, `didit_internal_id_list`, dan `delete_all` tidak ada atau kosong). Body error berupa array JSON.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing selector": {
                    "value": [
                      "Provide vendor_data_list, didit_internal_id_list, or set delete_all=true."
                    ]
                  }
                }
              }
            }
          },
          "403": {
            "description": "Kunci API tidak ada, tidak valid, atau dicabut, atau kunci tersebut tidak dapat menghapus bisnis untuk aplikasi ini. Kunci yang tidak ada mengembalikan `403`; kunci yang salah, dicabut, atau kedaluwarsa mengembalikan `401`.",
            "content": {
              "application/json": {
                "examples": {
                  "Forbidden": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Batas laju terlampaui; kurangi laju permintaan dan coba lagi setelah interval yang ditunjukkan dalam `Retry-After`.",
            "content": {
              "application/json": {
                "examples": {
                  "Rate limited": {
                    "value": {
                      "detail": "Request was throttled. Expected available in 30 seconds."
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "Tidak ada yang dihapus. `code` menyatakan alasannya: `in_filed_report` ketika pilihan mencakup perusahaan dalam laporan regulasi yang sudah final, `subject_deletion_in_progress` ketika permintaan lain masih menghapus salah satu perusahaan yang dipilih. Ulangi permintaan setelah penghapusan tersebut selesai.",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/InFiledReportError"
                    },
                    {
                      "$ref": "#/components/schemas/SubjectDeletionInProgressError"
                    }
                  ]
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/users/aml-monitoring/": {
      "post": {
        "summary": "Aktifkan atau nonaktifkan pemantauan AML berkelanjutan untuk pengguna",
        "description": "Mengaktifkan atau menonaktifkan pemantauan AML berkelanjutan untuk pengguna yang dipilih, dengan semantik yang sama seperti Business Console. Tepat satu skrining AML yang dipantau disimpan per pengguna, sehingga profil yang diverifikasi beberapa kali akan dipantau dan ditagih sekali; menonaktifkannya akan mematikan pemantauan di seluruh skrining profil tersebut. Pengguna tanpa skrining AML apa pun akan diskrining terlebih dahulu (ditagih sebagai skrining AML reguler) jika memiliki nama lengkap, tanggal lahir, dan negara yang diperlukan; jika tidak, pengguna tersebut akan dilaporkan sebagai `skipped_no_identity_data`.\n\nAtur `estimate_only: true` untuk melihat pratinjau jumlah dan biaya tanpa menulis apa pun. Pilihan 20 profil atau kurang diselesaikan secara inline dan mengembalikan `200` dengan pekerjaan yang selesai; pilihan yang lebih besar mengembalikan `202` dan berjalan di latar belakang - lakukan polling pada [Dapatkan pekerjaan pemantauan AML](#get-/v3/aml-monitoring/jobs/-job_id-/) dengan `job_id` yang dikembalikan. Pengaktifan ditolak dengan `403` jika saldo organisasi tidak mencukupi estimasi biaya. Pengenal yang tidak cocok dengan apa pun dicantumkan di `unmatched` dan tidak pernah menggagalkan permintaan: pilihan yang tidak cocok dengan apa pun selesai sebagai pekerjaan kosong (`total` 0), konvensi yang sama dengan endpoint penghapusan batch.",
        "operationId": "toggle_users_aml_monitoring",
        "x-didit-sdk": {
          "resource": "users",
          "method": "set_aml_monitoring",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "AML Ongoing Monitoring"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "is_enabled"
                ],
                "description": "Pilih pengguna dengan `vendor_data_list`, `didit_internal_id_list`, atau keduanya (kedua daftar digabungkan dengan OR). Maksimal 1000 pengidentifikasi per permintaan di kedua daftar.",
                "properties": {
                  "is_enabled": {
                    "type": "boolean",
                    "description": "true untuk mengaktifkan pemantauan, false untuk menonaktifkannya."
                  },
                  "estimate_only": {
                    "type": "boolean",
                    "default": false,
                    "description": "Jika true, mengembalikan estimasi biaya dan tidak melakukan penulisan data - tanpa skrining, tanpa penagihan, tanpa membuat job."
                  },
                  "vendor_data_list": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Pengenal Anda sendiri untuk pengguna yang akan dialihkan statusnya, dicocokkan persis seperti yang dikirimkan."
                  },
                  "didit_internal_id_list": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "description": "ID internal Didit dari pengguna yang akan dialihkan statusnya - `didit_internal_id` yang dikembalikan oleh endpoint pembuatan, pengambilan, dan daftar."
                  }
                }
              },
              "examples": {
                "Estimate first": {
                  "summary": "Pratinjau biaya tanpa menulis",
                  "value": {
                    "is_enabled": true,
                    "estimate_only": true,
                    "vendor_data_list": [
                      "user-123",
                      "user-456"
                    ]
                  }
                },
                "Enable": {
                  "summary": "Aktifkan pemantauan untuk dua pengguna",
                  "value": {
                    "is_enabled": true,
                    "vendor_data_list": [
                      "user-123",
                      "user-456"
                    ]
                  }
                },
                "Disable": {
                  "summary": "Nonaktifkan pemantauan berdasarkan id internal Didit",
                  "value": {
                    "is_enabled": false,
                    "didit_internal_id_list": [
                      "3f1c0d3e-8f0a-4c2e-9a3d-9b1f5f4a2c11"
                    ]
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://verification.didit.me/v3/users/aml-monitoring/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"is_enabled\": true, \"vendor_data_list\": [\"user-123\", \"user-456\"]}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.users.set_aml_monitoring(\n    is_enabled=True,\n    estimate_only=True,\n    vendor_data_list=[\"user-123\", \"user-456\"],\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.users.setAmlMonitoring({\n  is_enabled: true,\n  estimate_only: true,\n  vendor_data_list: [\"user-123\", \"user-456\"],\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Users.SetAMLMonitoring(ctx, didit.UsersSetAMLMonitoringParams{\n\tIsEnabled:      true,\n\tEstimateOnly:   didit.Bool(true),\n\tVendorDataList: didit.Some([]string{\"user-123\", \"user-456\"}),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.List;\nimport me.didit.Didit;\nimport me.didit.types.UsersSetAmlMonitoringParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.users().setAmlMonitoring(UsersSetAmlMonitoringParams.builder()\n        .isEnabled(true)\n        .estimateOnly(true)\n        .vendorDataList(List.of(\"user-123\", \"user-456\"))\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->users->setAmlMonitoring([\n    'is_enabled' => true,\n    'estimate_only' => true,\n    'vendor_data_list' => ['user-123', 'user-456'],\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.users.set_aml_monitoring(\n  is_enabled: true,\n  estimate_only: true,\n  vendor_data_list: [\"user-123\", \"user-456\"]\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Users.SetAmlMonitoringAsync(new UsersSetAmlMonitoringParams\n{\n    IsEnabled = true,\n    EstimateOnly = true,\n    VendorDataList = new string[] { \"user-123\", \"user-456\" },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "Estimasi (jika `estimate_only` bernilai true) atau pekerjaan yang telah selesai untuk pilihan yang diproses secara inline.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AMLMonitoringToggleResult"
                }
              }
            }
          },
          "202": {
            "description": "Pilihan yang lebih besar berjalan di latar belakang. Lakukan polling pada endpoint job dengan `job_id`; `results` akan terisi saat profil diproses.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AMLMonitoringJob"
                }
              }
            }
          },
          "400": {
            "description": "Kesalahan validasi: `is_enabled` tidak ada, tidak ada selektor, atau lebih dari 1000 pengidentifikasi di kedua daftar."
          },
          "401": {
            "description": "Kunci API tidak ada atau tidak valid."
          },
          "403": {
            "description": "Saldo tidak mencukupi untuk mengaktifkan pemantauan untuk pilihan ini. Respons menyertakan `estimate` sehingga Anda dapat mengisi saldo dalam jumlah yang tepat.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "estimate": {
                      "type": "object",
                      "description": "Pratinjau biaya. Dikembalikan secara langsung saat estimate_only bernilai true (tidak ada yang ditulis).",
                      "properties": {
                        "users_total": {
                          "type": "integer",
                          "description": "Profil yang cocok dengan pilihan."
                        },
                        "already_enabled": {
                          "type": "integer",
                          "description": "Profil yang sudah dipantau (tidak ada tindakan saat mengaktifkan; ini adalah profil yang dimatikan saat dinonaktifkan)."
                        },
                        "with_existing_aml": {
                          "type": "integer",
                          "description": "Profil yang skrining AML-nya yang sudah ada akan dialihkan ke dipantau (tanpa skrining baru)."
                        },
                        "needing_screening": {
                          "type": "integer",
                          "description": "Profil tanpa skrining AML apa pun yang akan diskrining terlebih dahulu (ditagih sebagai skrining AML reguler)."
                        },
                        "skipped_no_identity_data": {
                          "type": "integer",
                          "description": "Profil yang tidak dapat diskrining karena data identitas tidak tersedia."
                        },
                        "skipped_blocked": {
                          "type": "integer",
                          "description": "Pengguna terblokir yang akan dilewati (selalu 0 untuk bisnis)."
                        },
                        "estimated_screening_cost_usd": {
                          "type": "number",
                          "example": 0.2,
                          "description": "Biaya sekali bayar untuk skrining baru."
                        },
                        "estimated_annual_monitoring_cost_usd": {
                          "type": "number",
                          "example": 0.07,
                          "description": "Biaya pemantauan tahunan dari profil yang akan dipantau."
                        },
                        "balance_sufficient": {
                          "type": "boolean",
                          "description": "Apakah saldo organisasi mencukupi untuk skrining ditambah tahun pertama pemantauan."
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v3/businesses/aml-monitoring/": {
      "post": {
        "summary": "Aktifkan atau nonaktifkan pemantauan AML berkelanjutan untuk bisnis",
        "description": "Mengaktifkan atau menonaktifkan pemantauan AML berkelanjutan untuk bisnis yang dipilih, dengan semantik yang sama seperti Business Console. Tepat satu skrining AML yang dipantau disimpan per bisnis, sehingga profil yang diverifikasi beberapa kali akan dipantau dan ditagih sekali; menonaktifkannya akan mematikan pemantauan di seluruh skrining profil tersebut. Bisnis tanpa skrining AML apa pun akan diskrining terlebih dahulu (ditagih sebagai skrining AML reguler) jika memiliki nama resmi atau nama tampilan yang diperlukan; jika tidak, bisnis tersebut akan dilaporkan sebagai `skipped_no_identity_data`.\n\nAtur `estimate_only: true` untuk melihat pratinjau jumlah dan biaya tanpa menulis apa pun. Pilihan 20 profil atau kurang diselesaikan secara inline dan mengembalikan `200` dengan pekerjaan yang selesai; pilihan yang lebih besar mengembalikan `202` dan berjalan di latar belakang - lakukan polling pada [Dapatkan pekerjaan pemantauan AML](#get-/v3/aml-monitoring/jobs/-job_id-/) dengan `job_id` yang dikembalikan. Pengaktifan ditolak dengan `403` jika saldo organisasi tidak mencukupi estimasi biaya. Pengenal yang tidak cocok dengan apa pun dicantumkan di `unmatched` dan tidak pernah menggagalkan permintaan: pilihan yang tidak cocok dengan apa pun selesai sebagai pekerjaan kosong (`total` 0), konvensi yang sama dengan endpoint penghapusan batch.",
        "operationId": "toggle_businesses_aml_monitoring",
        "x-didit-sdk": {
          "resource": "businesses",
          "method": "set_aml_monitoring",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "AML Ongoing Monitoring"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "is_enabled"
                ],
                "description": "Pilih bisnis dengan `vendor_data_list`, `didit_internal_id_list`, atau keduanya (kedua daftar digabungkan dengan OR). Maksimal 1000 pengidentifikasi per permintaan di kedua daftar.",
                "properties": {
                  "is_enabled": {
                    "type": "boolean",
                    "description": "true untuk mengaktifkan pemantauan, false untuk menonaktifkannya."
                  },
                  "estimate_only": {
                    "type": "boolean",
                    "default": false,
                    "description": "Jika true, mengembalikan estimasi biaya dan tidak melakukan penulisan data - tanpa skrining, tanpa penagihan, tanpa membuat job."
                  },
                  "vendor_data_list": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Pengenal Anda sendiri untuk bisnis yang akan dialihkan statusnya, dicocokkan persis seperti yang dikirimkan."
                  },
                  "didit_internal_id_list": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "description": "ID internal Didit dari bisnis yang akan dialihkan statusnya - `didit_internal_id` yang dikembalikan oleh endpoint pembuatan, pengambilan, dan daftar."
                  }
                }
              },
              "examples": {
                "Estimate first": {
                  "summary": "Pratinjau biaya tanpa menulis",
                  "value": {
                    "is_enabled": true,
                    "estimate_only": true,
                    "vendor_data_list": [
                      "company-123",
                      "company-456"
                    ]
                  }
                },
                "Enable": {
                  "summary": "Aktifkan pemantauan untuk dua bisnis",
                  "value": {
                    "is_enabled": true,
                    "vendor_data_list": [
                      "company-123",
                      "company-456"
                    ]
                  }
                },
                "Disable": {
                  "summary": "Nonaktifkan pemantauan berdasarkan id internal Didit",
                  "value": {
                    "is_enabled": false,
                    "didit_internal_id_list": [
                      "3f1c0d3e-8f0a-4c2e-9a3d-9b1f5f4a2c11"
                    ]
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://verification.didit.me/v3/businesses/aml-monitoring/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"is_enabled\": true, \"vendor_data_list\": [\"company-123\", \"company-456\"]}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.businesses.set_aml_monitoring(\n    is_enabled=True,\n    estimate_only=True,\n    vendor_data_list=[\"company-123\", \"company-456\"],\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.businesses.setAmlMonitoring({\n  is_enabled: true,\n  estimate_only: true,\n  vendor_data_list: [\"company-123\", \"company-456\"],\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Businesses.SetAMLMonitoring(ctx, didit.BusinessesSetAMLMonitoringParams{\n\tIsEnabled:      true,\n\tEstimateOnly:   didit.Bool(true),\n\tVendorDataList: didit.Some([]string{\"company-123\", \"company-456\"}),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.List;\nimport me.didit.Didit;\nimport me.didit.types.BusinessesSetAmlMonitoringParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.businesses().setAmlMonitoring(BusinessesSetAmlMonitoringParams.builder()\n        .isEnabled(true)\n        .estimateOnly(true)\n        .vendorDataList(List.of(\"company-123\", \"company-456\"))\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->businesses->setAmlMonitoring([\n    'is_enabled' => true,\n    'estimate_only' => true,\n    'vendor_data_list' => ['company-123', 'company-456'],\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.businesses.set_aml_monitoring(\n  is_enabled: true,\n  estimate_only: true,\n  vendor_data_list: [\"company-123\", \"company-456\"]\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Businesses.SetAmlMonitoringAsync(new BusinessesSetAmlMonitoringParams\n{\n    IsEnabled = true,\n    EstimateOnly = true,\n    VendorDataList = new string[] { \"company-123\", \"company-456\" },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "Estimasi (jika `estimate_only` bernilai true) atau pekerjaan yang telah selesai untuk pilihan yang diproses secara inline.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AMLMonitoringToggleResult"
                }
              }
            }
          },
          "202": {
            "description": "Pilihan yang lebih besar berjalan di latar belakang. Lakukan polling pada endpoint job dengan `job_id`; `results` akan terisi saat profil diproses.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AMLMonitoringJob"
                }
              }
            }
          },
          "400": {
            "description": "Kesalahan validasi: `is_enabled` tidak ada, tidak ada selektor, atau lebih dari 1000 pengidentifikasi di kedua daftar."
          },
          "401": {
            "description": "Kunci API tidak ada atau tidak valid."
          },
          "403": {
            "description": "Saldo tidak mencukupi untuk mengaktifkan pemantauan untuk pilihan ini. Respons menyertakan `estimate` sehingga Anda dapat mengisi saldo dalam jumlah yang tepat.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "estimate": {
                      "type": "object",
                      "description": "Pratinjau biaya. Dikembalikan secara langsung saat estimate_only bernilai true (tidak ada yang ditulis).",
                      "properties": {
                        "users_total": {
                          "type": "integer",
                          "description": "Profil yang cocok dengan pilihan."
                        },
                        "already_enabled": {
                          "type": "integer",
                          "description": "Profil yang sudah dipantau (tidak ada tindakan saat mengaktifkan; ini adalah profil yang dimatikan saat dinonaktifkan)."
                        },
                        "with_existing_aml": {
                          "type": "integer",
                          "description": "Profil yang skrining AML-nya yang sudah ada akan dialihkan ke dipantau (tanpa skrining baru)."
                        },
                        "needing_screening": {
                          "type": "integer",
                          "description": "Profil tanpa skrining AML apa pun yang akan diskrining terlebih dahulu (ditagih sebagai skrining AML reguler)."
                        },
                        "skipped_no_identity_data": {
                          "type": "integer",
                          "description": "Profil yang tidak dapat diskrining karena data identitas tidak tersedia."
                        },
                        "skipped_blocked": {
                          "type": "integer",
                          "description": "Pengguna terblokir yang akan dilewati (selalu 0 untuk bisnis)."
                        },
                        "estimated_screening_cost_usd": {
                          "type": "number",
                          "example": 0.2,
                          "description": "Biaya sekali bayar untuk skrining baru."
                        },
                        "estimated_annual_monitoring_cost_usd": {
                          "type": "number",
                          "example": 0.07,
                          "description": "Biaya pemantauan tahunan dari profil yang akan dipantau."
                        },
                        "balance_sufficient": {
                          "type": "boolean",
                          "description": "Apakah saldo organisasi mencukupi untuk skrining ditambah tahun pertama pemantauan."
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v3/aml-monitoring/jobs/{job_id}/": {
      "get": {
        "summary": "Dapatkan tugas pemantauan AML berkelanjutan",
        "description": "Status, penghitung hasil, dan hasil untuk setiap catatan dari tugas pengaktifan atau penonaktifan pemantauan yang dimulai dari `POST /v3/users/aml-monitoring/` atau `POST /v3/businesses/aml-monitoring/`. Lakukan polling setiap beberapa detik saat `status` bernilai `PENDING` atau `PROCESSING`; `results` selesai setelah bernilai `COMPLETED`.",
        "operationId": "get_aml_monitoring_job",
        "x-didit-sdk": {
          "resource": "aml_monitoring",
          "method": "retrieve_job",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "AML Ongoing Monitoring"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "job_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "`job_id` yang dikembalikan oleh endpoint untuk mengubah status."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl 'https://verification.didit.me/v3/aml-monitoring/jobs/JOB_ID/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.aml_monitoring.retrieve_job(\n    \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.amlMonitoring.retrieveJob(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.AMLMonitoring.RetrieveJob(ctx, \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.amlMonitoring().retrieveJob(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->amlMonitoring->retrieveJob('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.aml_monitoring.retrieve_job(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.AmlMonitoring.RetrieveJobAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "Pekerjaan tersebut.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "job_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "PENDING",
                        "PROCESSING",
                        "COMPLETED",
                        "FAILED"
                      ]
                    },
                    "is_enabled": {
                      "type": "boolean",
                      "description": "true saat pekerjaan mengaktifkan pemantauan, false saat menonaktifkannya."
                    },
                    "target_type": {
                      "type": "string",
                      "enum": [
                        "user",
                        "business"
                      ],
                      "description": "Famili profil mana yang diaktif-nonaktifkan oleh tugas ini."
                    },
                    "total": {
                      "type": "integer",
                      "description": "Profil yang diproses oleh tugas."
                    },
                    "processed": {
                      "type": "integer",
                      "description": "Profil yang diproses sejauh ini."
                    },
                    "outcomes": {
                      "type": "object",
                      "description": "Penghitung hasil per rekaman. Setiap profil yang dipilih dipetakan ke tepat satu penghitung; tidak ada yang dilewati secara diam-diam.",
                      "properties": {
                        "enabled": {
                          "type": "integer",
                          "description": "Pemantauan diaktifkan pada skrining AML yang ada."
                        },
                        "screened_and_enabled": {
                          "type": "integer",
                          "description": "Skrining AML baru telah dibuat (ditagihkan) dan pemantauan diaktifkan untuk skrining tersebut."
                        },
                        "already_enabled": {
                          "type": "integer",
                          "description": "Pemantauan sudah aktif sebelumnya; tidak ada yang berubah dan tidak ada yang ditagihkan."
                        },
                        "disabled": {
                          "type": "integer",
                          "description": "Pemantauan dinonaktifkan di semua skrining AML profil."
                        },
                        "skipped_no_identity_data": {
                          "type": "integer",
                          "description": "Dilewati: profil tidak memiliki nama lengkap, tanggal lahir, dan negara (pengguna) atau nama (bisnis) yang diperlukan untuk diskrining."
                        },
                        "skipped_blocked": {
                          "type": "integer",
                          "description": "Dilewati: pengguna diblokir."
                        },
                        "skipped_sandbox": {
                          "type": "integer",
                          "description": "Dilewati: aplikasi sandbox, tidak ada skrining yang dibuat."
                        },
                        "failed_provider": {
                          "type": "integer",
                          "description": "Skrining tidak dapat diselesaikan; coba lagi nanti."
                        },
                        "failed_insufficient_balance": {
                          "type": "integer",
                          "description": "Saldo habis saat pekerjaan sedang berjalan."
                        }
                      }
                    },
                    "results": {
                      "type": "array",
                      "description": "Satu entri per profil yang diproses, sesuai urutan pemrosesan. Bertambah saat tugas berjalan; lengkap setelah statusnya COMPLETED. Dicatat untuk tugas yang dimulai melalui API; tugas yang dimulai dari Business Console hanya melaporkan jumlah.",
                      "items": {
                        "type": "object",
                        "properties": {
                          "didit_internal_id": {
                            "type": "string",
                            "format": "uuid",
                            "description": "ID internal Didit untuk profil tersebut."
                          },
                          "vendor_data": {
                            "type": "string",
                            "nullable": true,
                            "description": "Pengenal Anda sendiri untuk profil tersebut."
                          },
                          "outcome": {
                            "type": "string",
                            "enum": [
                              "enabled",
                              "screened_and_enabled",
                              "already_enabled",
                              "disabled",
                              "skipped_no_identity_data",
                              "skipped_blocked",
                              "skipped_sandbox",
                              "failed_provider",
                              "failed_insufficient_balance"
                            ]
                          }
                        }
                      }
                    },
                    "error": {
                      "type": "string",
                      "nullable": true,
                      "description": "Pesan kegagalan umum saat status FAILED; penyebab terperinci disimpan di sisi platform."
                    },
                    "created_at": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "completed_at": {
                      "type": "string",
                      "format": "date-time",
                      "nullable": true
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Kunci API tidak ada atau tidak valid."
          },
          "404": {
            "description": "Tidak ada job seperti itu untuk aplikasi ini."
          }
        }
      }
    },
    "/v3/users/{vendor_data}/update-status/": {
      "patch": {
        "summary": "Perbarui status pengguna",
        "description": "Ubah hanya `status` siklus hidup pengguna: `ACTIVE`, `FLAGGED`, atau `BLOCKED` (bukan status sesi). `BLOCKED` menambahkan `vendor_data` ke daftar blokir sistem; berpindah dari `BLOCKED` akan menghapus entri tersebut. Setiap perubahan dicatat sebagai aktivitas `STATUS_CHANGED` pada pengguna, dengan `reason` opsional sebagai `comment`-nya. Mengirim status saat ini tidak mengubah apa pun dan tidak mencatat `reason`. Webhook `user.status.updated` tidak memuat `reason`.",
        "operationId": "update_user_status",
        "x-didit-sdk": {
          "resource": "users",
          "method": "update_status",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Users"
        ],
        "parameters": [
          {
            "name": "vendor_data",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Pengidentifikasi unik Anda untuk pengguna."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "allOf": [
                  {
                    "$ref": "#/components/schemas/EntityStatusUpdateRequest"
                  },
                  {
                    "type": "object",
                    "properties": {
                      "reason": {
                        "type": "string",
                        "nullable": true,
                        "maxLength": 1000,
                        "description": "Alasan mengapa status berubah. Dicatat pada entri perubahan status aktivitas pengguna (`comments[].comment`, dan **Activity** di Business Console), hanya jika status benar-benar berubah. Webhook tidak menyertakannya."
                      }
                    }
                  }
                ]
              },
              "examples": {
                "Activate": {
                  "summary": "Aktifkan kembali pengguna",
                  "value": {
                    "status": "ACTIVE"
                  }
                },
                "Flag": {
                  "summary": "Tandai pengguna untuk ditinjau",
                  "value": {
                    "status": "FLAGGED"
                  }
                },
                "Block": {
                  "summary": "Blokir pengguna (menambahkan ke daftar blokir sistem)",
                  "value": {
                    "status": "BLOCKED"
                  }
                },
                "Block with reason": {
                  "summary": "Blokir pengguna dan catat alasannya",
                  "value": {
                    "status": "BLOCKED",
                    "reason": "Chargeback fraud pattern confirmed"
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X PATCH 'https://verification.didit.me/v3/users/user-abc-123/update-status/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"status\": \"BLOCKED\"}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.users.update_status(\n    \"user-123\",\n    status=\"ACTIVE\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.users.updateStatus(\"user-123\", {\n  status: \"ACTIVE\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Users.UpdateStatus(ctx, \"user-123\", didit.UsersUpdateStatusParams{\n\tStatus: \"ACTIVE\",\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.EntityStatusUpdateRequest;\nimport me.didit.types.UsersUpdateStatusParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.users().updateStatus(\"user-123\", UsersUpdateStatusParams.builder()\n        .status(EntityStatusUpdateRequest.Status.of(\"ACTIVE\"))\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->users->updateStatus('user-123', [\n    'status' => 'ACTIVE',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.users.update_status(\n  \"user-123\",\n  status: \"ACTIVE\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Users.UpdateStatusAsync(\"user-123\", new UsersUpdateStatusParams\n{\n    Status = \"ACTIVE\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "Status pengguna diperbarui. Rekor pengguna lengkap dikembalikan.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserDetailItem"
                },
                "examples": {
                  "Blocked": {
                    "value": {
                      "didit_internal_id": "f4e5e1f2-94a9-4f86-8c16-2b7d9b4db418",
                      "vendor_data": "user-abc-123",
                      "display_name": null,
                      "full_name": "John Michael Doe",
                      "date_of_birth": "1990-05-15",
                      "effective_name": "John Michael Doe",
                      "status": "BLOCKED",
                      "metadata": {
                        "tier": "premium",
                        "source": "website"
                      },
                      "portrait_image_url": "https://<media-host>/...",
                      "session_count": 3,
                      "approved_count": 2,
                      "declined_count": 0,
                      "in_review_count": 1,
                      "issuing_states": [
                        "USA"
                      ],
                      "approved_emails": [
                        "john@example.com"
                      ],
                      "approved_phones": [
                        "+14155551234"
                      ],
                      "features": {
                        "ID_VERIFICATION": "Approved",
                        "LIVENESS": "Approved",
                        "FACE_MATCH": "Approved",
                        "AML": "Approved"
                      },
                      "features_list": [
                        {
                          "feature": "ID_VERIFICATION",
                          "status": "Approved"
                        },
                        {
                          "feature": "LIVENESS",
                          "status": "Approved"
                        },
                        {
                          "feature": "FACE_MATCH",
                          "status": "Approved"
                        },
                        {
                          "feature": "AML",
                          "status": "Approved"
                        }
                      ],
                      "last_session_at": "2025-06-15T10:30:00Z",
                      "last_activity_at": "2025-06-15T10:30:00Z",
                      "first_session_at": "2025-06-01T08:00:00Z",
                      "tags": [
                        {
                          "uuid": "9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d",
                          "tag": {
                            "uuid": "e1f2a3b4-c5d6-4e7f-8a9b-0c1d2e3f4a5b",
                            "name": "VIP",
                            "color": "#2567FF",
                            "description": null,
                            "source": "custom",
                            "created_at": "2025-05-01T09:00:00Z",
                            "updated_at": "2025-05-01T09:00:00Z"
                          },
                          "added_by_email": "analyst@acme.com",
                          "added_by_name": "Jane Analyst",
                          "created_at": "2025-06-02T11:00:00Z"
                        }
                      ],
                      "comments": [
                        {
                          "uuid": "c1111111-2222-4333-8444-555555555555",
                          "comment_type": "STATUS_CHANGED",
                          "comment": "Chargeback fraud pattern confirmed",
                          "actor_email": null,
                          "actor_name": null,
                          "previous_status": "ACTIVE",
                          "new_status": "BLOCKED",
                          "previous_value": null,
                          "new_value": null,
                          "changed_fields": [],
                          "metadata": null,
                          "mentioned_emails": [],
                          "created_at": "2025-06-15T10:30:00Z"
                        }
                      ],
                      "created_at": "2025-06-01T08:00:00Z",
                      "updated_at": "2025-06-15T10:30:00Z"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "`status` tidak ada atau tidak valid, atau `reason` lebih dari 1000 karakter.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing status": {
                    "value": {
                      "status": [
                        "This field is required."
                      ]
                    }
                  },
                  "Bad status": {
                    "value": {
                      "status": [
                        "Invalid status. Valid options are: ACTIVE, FLAGGED, BLOCKED"
                      ]
                    }
                  },
                  "Reason too long": {
                    "value": {
                      "reason": [
                        "Ensure this field has no more than 1000 characters."
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Tidak ada kredensial yang diberikan. Permintaan ke jalur `/v3/users/*` tanpa header `x-api-key` (atau token `Authorization: Bearer`) akan ditolak oleh middleware autentikasi sebelum mencapai API.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing credentials": {
                    "value": {
                      "detail": "You must be authenticated with a valid access token to access this endpoint."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Kunci tidak dapat memperbarui pengguna untuk aplikasi ini. Kunci yang hilang mengembalikan `403`; kunci yang salah, dicabut, atau kedaluwarsa mengembalikan `401`.",
            "content": {
              "application/json": {
                "examples": {
                  "Forbidden": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Tidak ada pengguna (yang belum dihapus) dengan `vendor_data` yang diberikan untuk aplikasi ini.",
            "content": {
              "application/json": {
                "examples": {
                  "Not found": {
                    "value": {
                      "detail": "Not found."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Batas laju terlampaui; kurangi laju permintaan dan coba lagi setelah interval yang ditunjukkan dalam `Retry-After`.",
            "content": {
              "application/json": {
                "examples": {
                  "Rate limited": {
                    "value": {
                      "detail": "Request was throttled. Expected available in 30 seconds."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/businesses/create/": {
      "post": {
        "summary": "Buat bisnis",
        "description": "Buat [bisnis](/entities/businesses) terlebih dahulu *tanpa* sesi KYB. Semua kolom bersifat opsional, tetapi Anda harus selalu mengirimkan `vendor_data` — tanpanya catatan tidak dapat ditautkan ke sesi atau transaksi. Jika diberikan, `vendor_data` harus unik di antara bisnis yang tidak dihapus (kecocokan persis; konflik menghasilkan 400). Tidak idempoten.",
        "operationId": "create_business",
        "x-didit-sdk": {
          "resource": "businesses",
          "method": "create",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Businesses"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "vendor_data": {
                    "type": "string",
                    "nullable": true,
                    "description": "Pengidentifikasi unik Anda untuk bisnis ini (string bentuk bebas, BUKAN UUID). Opsional tetapi sangat disarankan. Jika diberikan, harus unik di antara bisnis yang tidak dihapus untuk aplikasi tersebut; dicocokkan persis seperti yang dikirim."
                  },
                  "display_name": {
                    "type": "string",
                    "nullable": true,
                    "maxLength": 255,
                    "description": "Nama tampilan yang mudah dipahami yang ditampilkan di konsol (mengambil prioritas di atas `legal_name` untuk tampilan antarmuka)."
                  },
                  "legal_name": {
                    "type": "string",
                    "nullable": true,
                    "maxLength": 255,
                    "description": "Nama resmi menurut hukum dari perusahaan."
                  },
                  "registration_number": {
                    "type": "string",
                    "nullable": true,
                    "maxLength": 100,
                    "description": "Nomor registrasi atau nomor pendirian perusahaan."
                  },
                  "country_code": {
                    "type": "string",
                    "nullable": true,
                    "maxLength": 10,
                    "description": "Negara pendirian (ISO 3166-1 alpha-2, misalnya `GB`, `US`)."
                  },
                  "status": {
                    "type": "string",
                    "enum": [
                      "ACTIVE",
                      "FLAGGED",
                      "BLOCKED"
                    ],
                    "default": "ACTIVE",
                    "description": "Status siklus hidup awal. Default-nya adalah `ACTIVE`."
                  },
                  "metadata": {
                    "type": "object",
                    "nullable": true,
                    "description": "Objek JSON arbitrer yang Anda lampirkan ke bisnis. Defaultnya adalah `{}`."
                  }
                }
              },
              "examples": {
                "Basic": {
                  "summary": "Minimum yang disarankan",
                  "value": {
                    "vendor_data": "company-456",
                    "legal_name": "New Corp Ltd",
                    "country_code": "US"
                  }
                },
                "Full": {
                  "summary": "Semua kolom",
                  "value": {
                    "vendor_data": "company-789",
                    "display_name": "New Corp",
                    "legal_name": "New Corp International Ltd",
                    "registration_number": "98765432",
                    "country_code": "DE",
                    "status": "ACTIVE",
                    "metadata": {
                      "industry": "fintech",
                      "tier": "enterprise"
                    }
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://verification.didit.me/v3/businesses/create/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"vendor_data\": \"company-456\", \"legal_name\": \"New Corp Ltd\", \"country_code\": \"US\"}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.businesses.create(\n    vendor_data=\"company-456\",\n    legal_name=\"New Corp Ltd\",\n    country_code=\"US\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.businesses.create({\n  vendor_data: \"company-456\",\n  legal_name: \"New Corp Ltd\",\n  country_code: \"US\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Businesses.Create(ctx, didit.BusinessesCreateParams{\n\tVendorData:  didit.String(\"company-456\"),\n\tLegalName:   didit.String(\"New Corp Ltd\"),\n\tCountryCode: didit.String(\"US\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.BusinessesCreateParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.businesses().create(BusinessesCreateParams.builder()\n        .vendorData(\"company-456\")\n        .legalName(\"New Corp Ltd\")\n        .countryCode(\"US\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->businesses->create([\n    'vendor_data' => 'company-456',\n    'legal_name' => 'New Corp Ltd',\n    'country_code' => 'US',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.businesses.create(\n  vendor_data: \"company-456\",\n  legal_name: \"New Corp Ltd\",\n  country_code: \"US\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Businesses.CreateAsync(new BusinessesCreateParams\n{\n    VendorData = \"company-456\",\n    LegalName = \"New Corp Ltd\",\n    CountryCode = \"US\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "201": {
            "description": "Bisnis berhasil dibuat. Data bisnis lengkap dikembalikan (struktur yang sama seperti Dapatkan Bisnis).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BusinessDetailItem"
                },
                "examples": {
                  "Created": {
                    "value": {
                      "didit_internal_id": "a1b2c3d4-e5f6-4890-abcd-ef1234567890",
                      "vendor_data": "company-456",
                      "display_name": null,
                      "legal_name": "New Corp Ltd",
                      "registration_number": null,
                      "country_code": "US",
                      "effective_name": "New Corp Ltd",
                      "status": "ACTIVE",
                      "session_count": 0,
                      "approved_count": 0,
                      "declined_count": 0,
                      "in_review_count": 0,
                      "features": {},
                      "features_list": [],
                      "last_session_at": null,
                      "last_activity_at": "2026-03-15T10:30:00Z",
                      "first_session_at": null,
                      "tags": [],
                      "created_at": "2026-03-15T10:30:00Z",
                      "metadata": {},
                      "updated_at": "2026-03-15T10:30:00Z"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Body tidak valid — biasanya duplikat `vendor_data`, `status` yang tidak dikenal, atau `metadata` yang salah format.",
            "content": {
              "application/json": {
                "examples": {
                  "Duplicate": {
                    "value": {
                      "vendor_data": [
                        "A business with this vendor_data already exists."
                      ]
                    }
                  },
                  "Bad status": {
                    "value": {
                      "status": [
                        "Invalid status. Valid options are: ACTIVE, FLAGGED, BLOCKED"
                      ]
                    }
                  },
                  "Bad metadata": {
                    "value": {
                      "metadata": [
                        "Metadata must be a JSON object."
                      ]
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Kunci API tidak ada, tidak valid, atau dicabut, atau kunci tidak dapat membuat bisnis untuk aplikasi ini. Kunci yang tidak ada mengembalikan `403`; kunci yang salah, dicabut, atau kedaluwarsa mengembalikan `401`.",
            "content": {
              "application/json": {
                "examples": {
                  "Forbidden": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Batas laju terlampaui; kurangi laju permintaan dan coba lagi setelah interval yang ditunjukkan dalam `Retry-After`.",
            "content": {
              "application/json": {
                "examples": {
                  "Rate limited": {
                    "value": {
                      "detail": "Request was throttled. Expected available in 30 seconds."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/users/create/": {
      "post": {
        "summary": "Buat pengguna",
        "description": "Buat [pengguna](/entities/users) berdasarkan `vendor_data`, sebelum atau tanpa sesi verifikasi. `vendor_data` harus unik di antara pengguna aplikasi (duplikat mengembalikan `400`). Tidak idempoten.\n\n**Detail kontak:** `email` dan `phone_number` disimpan di `metadata.contact`, dan `country` di `metadata.address`. Saat Anda mengirim `first_name` atau `last_name` tanpa `full_name`, Didit menggabungkannya menjadi `full_name`.\n\n**Tautan verifikasi:** dengan `send_verification_link: true`, Didit juga membuat sesi verifikasi untuk orang tersebut pada `workflow_id` dan mengirimkan tautannya ke `email`. Sesi ini menjalankan pemeriksaan yang sama seperti [Create Session](/id/sessions-api/create-session), seperti daftar blokir dan saldo kredit Anda. Orang dan sesi tersebut dibuat bersamaan atau tidak sama sekali: jika ada pemeriksaan yang gagal, tidak ada data yang ditulis dan tidak ada email yang dikirim. `verification_link` pada respons mendeskripsikan sesi tersebut, dan bernilai `null` jika Anda tidak meminta tautan.\n\n**Akses kunci API:** kunci API dengan cakupan terbatas memerlukan izin tulis `users`. Dengan `send_verification_link: true`, kunci ini juga memerlukan izin tulis `sessions`, atau panggilan akan mengembalikan `403` sebelum ada data yang ditulis. Kunci akses penuh tidak terpengaruh. Lihat [kunci API](/id/console/api-keys).",
        "operationId": "create_user",
        "x-didit-sdk": {
          "resource": "users",
          "method": "create",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Users"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "vendor_data"
                ],
                "properties": {
                  "vendor_data": {
                    "type": "string",
                    "description": "Pengidentifikasi unik Anda untuk pengguna ini (string bentuk bebas, BUKAN UUID). Harus unik di antara pengguna aplikasi; dicocokkan persis seperti yang dikirim."
                  },
                  "full_name": {
                    "type": "string",
                    "nullable": true,
                    "maxLength": 512,
                    "description": "Nama lengkap resmi pengguna."
                  },
                  "display_name": {
                    "type": "string",
                    "nullable": true,
                    "description": "Nama tampilan yang mudah dipahami yang ditampilkan di konsol (lebih diutamakan daripada `full_name` untuk tampilan UI).",
                    "maxLength": 255
                  },
                  "date_of_birth": {
                    "type": "string",
                    "format": "date",
                    "nullable": true,
                    "description": "Tanggal lahir dalam format `YYYY-MM-DD`."
                  },
                  "status": {
                    "type": "string",
                    "enum": [
                      "ACTIVE",
                      "FLAGGED",
                      "BLOCKED"
                    ],
                    "default": "ACTIVE",
                    "description": "Status siklus hidup awal. Default-nya adalah `ACTIVE`."
                  },
                  "metadata": {
                    "type": "object",
                    "nullable": true,
                    "description": "Objek JSON arbitrer yang Anda lampirkan ke pengguna. Defaultnya adalah `{}`."
                  },
                  "approved_emails": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Alamat email yang dipercaya sebelumnya untuk pengguna ini, mis. `[\"john@example.com\"]`."
                  },
                  "approved_phones": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Nomor telepon yang dipercaya sebelumnya untuk pengguna ini, mis. `[\"+14155551234\"]`."
                  },
                  "issuing_states": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Negara penerbit yang direkam sebelumnya (ISO 3166-1 alpha-3), mis. `[\"USA\"]`."
                  },
                  "first_name": {
                    "type": "string",
                    "maxLength": 255,
                    "description": "Nama depan. Ketika `full_name` tidak dikirimkan, Didit menggabungkan `first_name` dan `last_name` dengan spasi menjadi `full_name`. Tidak dikembalikan sebagai kolom terpisah."
                  },
                  "last_name": {
                    "type": "string",
                    "maxLength": 255,
                    "description": "Nama keluarga. Digabungkan dengan `first_name` menjadi `full_name` ketika `full_name` tidak dikirimkan. Tidak dikembalikan sebagai kolom terpisah."
                  },
                  "email": {
                    "type": "string",
                    "format": "email",
                    "description": "Email kontak, disimpan di `metadata.contact.email` (ini menggantikan `email` yang Anda kirimkan di dalam `metadata.contact`). Wajib diisi jika `send_verification_link` bernilai `true`: tautan akan dikirim ke alamat ini. Jika `metadata.contact` bukan objek JSON, panggilan akan menghasilkan respons `400` pada kolom ini."
                  },
                  "phone_number": {
                    "type": "string",
                    "maxLength": 32,
                    "description": "Nomor telepon kontak, disimpan di `metadata.contact.phone_number`. Jika `metadata.contact` bukan objek JSON, permintaan akan mengembalikan respons `400` untuk kolom ini."
                  },
                  "country": {
                    "type": "string",
                    "maxLength": 3,
                    "description": "Negara sebagai kode ISO 3166, alpha-2 atau alpha-3 (`ES` atau `ESP`). Disimpan dalam huruf besar di `metadata.address.country`. Jika `metadata.address` bukan objek JSON, panggilan akan merespons `400` pada kolom ini."
                  },
                  "send_verification_link": {
                    "type": "boolean",
                    "default": false,
                    "description": "Jika `true`, Didit membuat sesi verifikasi untuk orang tersebut pada `workflow_id` dan mengirimkan tautan melalui email ke `email`. Memerlukan `email` dan `workflow_id`. Kunci API dengan cakupan juga memerlukan izin tulis `sessions`."
                  },
                  "workflow_id": {
                    "type": "string",
                    "format": "uuid",
                    "description": "Alur kerja sesi verifikasi. Wajib diisi ketika `send_verification_link` bernilai `true`. Alur kerja ini harus memverifikasi perorangan: alur kerja Verifikasi Bisnis (KYB) akan ditolak. Jika tidak, parameter ini diabaikan."
                  },
                  "language": {
                    "type": "string",
                    "maxLength": 10,
                    "description": "Bahasa email verifikasi, sebagai kode [bahasa yang didukung](/id/integration/supported-languages). Bahasa Inggris jika diabaikan. Diabaikan jika `send_verification_link` bukan `true`."
                  }
                }
              },
              "examples": {
                "Basic": {
                  "summary": "Buat dengan info dasar",
                  "value": {
                    "vendor_data": "user-abc-123",
                    "full_name": "John Doe"
                  }
                },
                "Full": {
                  "summary": "Semua kolom",
                  "value": {
                    "vendor_data": "user-abc-456",
                    "full_name": "Jane Smith",
                    "display_name": "Jane S.",
                    "date_of_birth": "1990-05-15",
                    "status": "ACTIVE",
                    "metadata": {
                      "tier": "premium",
                      "source": "api"
                    },
                    "approved_emails": [
                      "jane@example.com"
                    ]
                  }
                },
                "Contact details": {
                  "summary": "Nama, email, telepon, dan negara",
                  "value": {
                    "vendor_data": "user-abc-789",
                    "first_name": "Julia",
                    "last_name": "Martin",
                    "email": "julia.martin@example.com",
                    "phone_number": "+34600000000",
                    "country": "ES"
                  }
                },
                "With verification link": {
                  "summary": "Buat orang tersebut dan kirimkan tautan verifikasi melalui email",
                  "value": {
                    "vendor_data": "user-abc-789",
                    "first_name": "Julia",
                    "last_name": "Martin",
                    "email": "julia.martin@example.com",
                    "send_verification_link": true,
                    "workflow_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                    "language": "es"
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://verification.didit.me/v3/users/create/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"vendor_data\": \"user-abc-123\", \"full_name\": \"John Doe\"}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.users.create(\n    vendor_data=\"user-abc-123\",\n    full_name=\"John Doe\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.users.create({\n  vendor_data: \"user-abc-123\",\n  full_name: \"John Doe\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Users.Create(ctx, didit.UsersCreateParams{\n\tVendorData: \"user-abc-123\",\n\tFullName:   didit.String(\"John Doe\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.UsersCreateParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.users().create(UsersCreateParams.builder()\n        .vendorData(\"user-abc-123\")\n        .fullName(\"John Doe\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->users->create([\n    'vendor_data' => 'user-abc-123',\n    'full_name' => 'John Doe',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.users.create(\n  vendor_data: \"user-abc-123\",\n  full_name: \"John Doe\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Users.CreateAsync(new UsersCreateParams\n{\n    VendorData = \"user-abc-123\",\n    FullName = \"John Doe\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "201": {
            "description": "Pengguna dibuat. Data pengguna lengkap (bentuk yang sama seperti Dapatkan Pengguna), ditambah `verification_link`: sesi verifikasi yang dikirim melalui email oleh Didit saat `send_verification_link` bernilai `true`, jika tidak `null`.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/UserDetailItem"
                    },
                    {
                      "type": "object",
                      "required": [
                        "verification_link"
                      ],
                      "properties": {
                        "verification_link": {
                          "type": "object",
                          "nullable": true,
                          "description": "Sesi verifikasi yang dibuat dan dikirimkan Didit melalui email kepada orang tersebut. Selalu ada: `null` jika `send_verification_link` tidak bernilai `true`.",
                          "required": [
                            "session_id",
                            "session_number",
                            "status",
                            "url",
                            "workflow_id",
                            "email"
                          ],
                          "properties": {
                            "session_id": {
                              "type": "string",
                              "format": "uuid",
                              "description": "ID sesi verifikasi."
                            },
                            "session_number": {
                              "type": "integer",
                              "description": "Nomor urut sesi di dalam aplikasi Anda."
                            },
                            "status": {
                              "type": "string",
                              "description": "Status sesi, `Not Started` untuk sesi yang baru saja dibuat."
                            },
                            "url": {
                              "type": "string",
                              "format": "uri",
                              "description": "Tautan verifikasi yang dikirimkan Didit melalui email kepada orang tersebut."
                            },
                            "workflow_id": {
                              "type": "string",
                              "format": "uuid",
                              "nullable": true,
                              "description": "Alur kerja yang dijalankan oleh sesi."
                            },
                            "email": {
                              "type": "string",
                              "format": "email",
                              "description": "Alamat tujuan pengiriman tautan."
                            }
                          }
                        }
                      }
                    }
                  ]
                },
                "examples": {
                  "Created": {
                    "value": {
                      "didit_internal_id": "f4e5e1f2-94a9-4f86-8c16-2b7d9b4db418",
                      "vendor_data": "user-abc-123",
                      "display_name": null,
                      "full_name": "John Doe",
                      "date_of_birth": null,
                      "effective_name": "John Doe",
                      "status": "ACTIVE",
                      "metadata": {},
                      "portrait_image_url": null,
                      "session_count": 0,
                      "approved_count": 0,
                      "declined_count": 0,
                      "in_review_count": 0,
                      "issuing_states": [],
                      "approved_emails": [],
                      "approved_phones": [],
                      "features": {},
                      "features_list": [],
                      "last_session_at": null,
                      "last_activity_at": "2025-06-15T10:30:00Z",
                      "first_session_at": null,
                      "tags": [],
                      "comments": [],
                      "created_at": "2025-06-15T10:30:00Z",
                      "updated_at": "2025-06-15T10:30:00Z",
                      "verification_link": null
                    }
                  },
                  "Created with verification link": {
                    "value": {
                      "didit_internal_id": "9b2f6c1e-3d4a-4e5f-8a7b-1c2d3e4f5a6b",
                      "vendor_data": "user-abc-789",
                      "display_name": null,
                      "full_name": "Julia Martin",
                      "date_of_birth": null,
                      "effective_name": "Julia Martin",
                      "status": "ACTIVE",
                      "metadata": {
                        "contact": {
                          "email": "julia.martin@example.com"
                        }
                      },
                      "portrait_image_url": null,
                      "session_count": 1,
                      "approved_count": 0,
                      "declined_count": 0,
                      "in_review_count": 0,
                      "issuing_states": [],
                      "approved_emails": [],
                      "approved_phones": [],
                      "features": {},
                      "features_list": [],
                      "last_session_at": "2025-06-15T10:30:00Z",
                      "last_activity_at": "2025-06-15T10:30:00Z",
                      "first_session_at": "2025-06-15T10:30:00Z",
                      "tags": [],
                      "comments": [],
                      "created_at": "2025-06-15T10:30:00Z",
                      "updated_at": "2025-06-15T10:30:00Z",
                      "verification_link": {
                        "session_id": "3fa85f64-5717-4562-b3fc-2c963f66afa7",
                        "session_number": 43762,
                        "status": "Not Started",
                        "url": "https://verify.didit.me/en/session/3FaJ9wLqX2Mz",
                        "workflow_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                        "email": "julia.martin@example.com"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Body tidak valid, diberi kunci berdasarkan kolom: biasanya duplikat `vendor_data`, kolom wajib yang hilang, atau nilai yang salah format. Dengan `send_verification_link: true`, juga `email` atau `workflow_id` yang hilang, alur kerja Verifikasi Bisnis (KYB) atau tidak dikenal, `language` yang tidak didukung (berkunci `contact_details.email_lang`), `vendor_data` yang masuk daftar blokir, atau kredit terlalu sedikit untuk memulai sesi. Tidak ada yang ditulis.",
            "content": {
              "application/json": {
                "examples": {
                  "Duplicate": {
                    "value": {
                      "vendor_data": [
                        "A user with this vendor_data already exists."
                      ]
                    }
                  },
                  "Missing vendor_data": {
                    "value": {
                      "vendor_data": [
                        "This field is required."
                      ]
                    }
                  },
                  "Bad metadata": {
                    "value": {
                      "metadata": [
                        "Metadata must be a JSON object."
                      ]
                    }
                  },
                  "Bad status": {
                    "value": {
                      "status": [
                        "Invalid status. Valid options are: ACTIVE, FLAGGED, BLOCKED"
                      ]
                    }
                  },
                  "Bad country": {
                    "value": {
                      "country": [
                        "Use an ISO 3166 country code, like ES or ESP."
                      ]
                    }
                  },
                  "Contact not an object": {
                    "value": {
                      "email": [
                        "metadata.contact must be a JSON object to store this value."
                      ]
                    }
                  },
                  "Address not an object": {
                    "value": {
                      "country": [
                        "metadata.address must be a JSON object to store this value."
                      ]
                    }
                  },
                  "Link without email or workflow": {
                    "value": {
                      "email": [
                        "An email address is required to send a verification link."
                      ],
                      "workflow_id": [
                        "Pick the workflow to send a verification link for."
                      ]
                    }
                  },
                  "Unknown workflow": {
                    "value": {
                      "workflow_id": [
                        "Invalid workflow_id."
                      ]
                    }
                  },
                  "Business workflow": {
                    "value": {
                      "workflow_id": [
                        "This workflow verifies a business. Pick a workflow that verifies a person to send them a verification link."
                      ]
                    }
                  },
                  "Blocklisted vendor_data": {
                    "value": {
                      "vendor_data": "This user or business has been blocked and cannot create new verification sessions."
                    }
                  },
                  "Insufficient credits": {
                    "value": {
                      "detail": "You don't have enough credits to perform this request. Please top up at https://business.didit.me"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Tidak ada kredensial yang diberikan. Permintaan ke jalur `/v3/users/*` tanpa header `x-api-key` (atau token `Authorization: Bearer`) akan ditolak oleh middleware autentikasi sebelum mencapai API.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing credentials": {
                    "value": {
                      "detail": "You must be authenticated with a valid access token to access this endpoint."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Kunci API tidak valid atau dicabut, atau kunci tidak dapat membuat pengguna untuk aplikasi ini. Kunci API dengan cakupan memerlukan izin tulis `users`, dan juga izin tulis `sessions` jika `send_verification_link` bernilai `true`; tidak ada yang ditulis. Kunci yang hilang mengembalikan `403`; kunci yang salah, dicabut, atau kedaluwarsa mengembalikan `401`.",
            "content": {
              "application/json": {
                "examples": {
                  "Forbidden": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "No sessions write": {
                    "summary": "Kunci ber-scope meminta tautan verifikasi tanpa izin tulis sessions",
                    "value": {
                      "detail": "This API key has no write access to sessions."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Batas laju terlampaui; kurangi laju permintaan dan coba lagi setelah interval yang ditunjukkan dalam `Retry-After`.",
            "content": {
              "application/json": {
                "examples": {
                  "Rate limited": {
                    "value": {
                      "detail": "Request was throttled. Expected available in 30 seconds."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/vendor-users/by-id/{didit_internal_id}/faces/upload/": {
      "post": {
        "summary": "Unggah wajah pengguna",
        "description": "Lampirkan gambar wajah tepercaya yang diimpor ke profil Pengguna yang ada. Gunakan ini setelah membuat atau mengambil Pengguna berdasarkan `vendor_data` dan membaca `didit_internal_id`-nya. Wajah yang diunggah disimpan di profil Pengguna dan diindeks untuk deteksi duplikat serta pencarian wajah. Wajah tersebut tidak ditambahkan ke daftar blokir wajah.",
        "operationId": "upload_user_face",
        "x-didit-sdk": {
          "resource": "users",
          "method": "upload_face",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Users"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID organisasi yang memiliki aplikasi."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID aplikasi yang memiliki profil Pengguna."
          },
          {
            "name": "didit_internal_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID Pengguna internal Didit, dikembalikan sebagai `didit_internal_id` oleh `GET /v3/users/{vendor_data}/` dan `POST /v3/users/create/`."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "image"
                ],
                "properties": {
                  "image": {
                    "type": "string",
                    "format": "byte",
                    "description": "Gambar wajah mentah JPG atau PNG berenkode base64. Jangan sertakan awalan `data:image/...;base64,`. Ukuran maksimum setelah didekode: 2 MB."
                  },
                  "comment": {
                    "type": "string",
                    "description": "Catatan opsional yang dapat dilihat operator untuk wajah yang diunggah.",
                    "default": ""
                  }
                }
              },
              "examples": {
                "Imported face": {
                  "summary": "Lampirkan wajah yang diimpor dari penyedia sebelumnya",
                  "value": {
                    "image": "/9j/4AAQSkZJRgABAQEA...",
                    "comment": "Imported from previous KYC provider"
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/vendor-users/by-id/f4e5e1f2-94a9-4f86-8c16-2b7d9b4db418/faces/upload/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"image\": \"/9j/4AAQSkZJRgABAQEA...\", \"comment\": \"Imported from previous KYC provider\"}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.users.upload_face(\n    \"11111111-2222-3333-4444-555555555555\",\n    image=\"/9j/4AAQSkZJRgABAQEA...\",\n    comment=\"Imported from previous KYC provider\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.users.uploadFace(\"11111111-2222-3333-4444-555555555555\", {\n  image: \"/9j/4AAQSkZJRgABAQEA...\",\n  comment: \"Imported from previous KYC provider\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Users.UploadFace(ctx, \"11111111-2222-3333-4444-555555555555\", didit.UsersUploadFaceParams{\n\tImage:   \"/9j/4AAQSkZJRgABAQEA...\",\n\tComment: didit.String(\"Imported from previous KYC provider\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.UsersUploadFaceParams;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.users().uploadFace(\"11111111-2222-3333-4444-555555555555\", UsersUploadFaceParams.builder()\n        .image(\"/9j/4AAQSkZJRgABAQEA...\")\n        .comment(\"Imported from previous KYC provider\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->users->uploadFace('11111111-2222-3333-4444-555555555555', [\n    'image' => '/9j/4AAQSkZJRgABAQEA...',\n    'comment' => 'Imported from previous KYC provider',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.users.upload_face(\n  \"11111111-2222-3333-4444-555555555555\",\n  image: \"/9j/4AAQSkZJRgABAQEA...\",\n  comment: \"Imported from previous KYC provider\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Users.UploadFaceAsync(\"11111111-2222-3333-4444-555555555555\", new UsersUploadFaceParams\n{\n    Image = \"/9j/4AAQSkZJRgABAQEA...\",\n    Comment = \"Imported from previous KYC provider\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "201": {
            "description": "Wajah diunggah dan dilampirkan ke profil Pengguna.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "uuid",
                    "image_url",
                    "comment",
                    "uploaded_by",
                    "created_at"
                  ],
                  "properties": {
                    "uuid": {
                      "type": "string",
                      "format": "uuid",
                      "description": "UUID rekaman wajah Pengguna yang diunggah."
                    },
                    "image_url": {
                      "type": "string",
                      "format": "uri",
                      "nullable": true,
                      "description": "URL bertanda tangan untuk gambar wajah yang diunggah."
                    },
                    "comment": {
                      "type": "string",
                      "nullable": true,
                      "description": "Komentar yang diberikan saat wajah diunggah."
                    },
                    "uploaded_by": {
                      "type": "string",
                      "nullable": true,
                      "description": "Email atau pengidentifikasi aktor pengunggah jika tersedia."
                    },
                    "created_at": {
                      "type": "string",
                      "format": "date-time",
                      "description": "Stempel waktu unggahan."
                    }
                  }
                },
                "examples": {
                  "Uploaded": {
                    "value": {
                      "uuid": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee",
                      "image_url": "https://signed-url.example/face.jpg",
                      "comment": "Imported from previous KYC provider",
                      "uploaded_by": "api",
                      "created_at": "2026-05-18T12:00:00Z"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Body permintaan atau gambar tidak valid. Penyebab umum: base64 tidak valid, gambar tidak valid, tidak ada wajah yang terdeteksi, gambar lebih dari 2 MB, embedding hilang, atau Pengguna sudah memiliki 5 wajah yang diunggah.",
            "content": {
              "application/json": {
                "examples": {
                  "No face": {
                    "value": {
                      "image": "No face detected in the image. Please upload a clear photo with a visible face."
                    }
                  },
                  "Too many faces": {
                    "value": {
                      "detail": "Maximum of 5 faces per user reached."
                    }
                  },
                  "Too large": {
                    "value": {
                      "image": "Image exceeds maximum size of 2 MB."
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Kunci API tidak ada atau tidak valid.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing key": {
                    "value": {
                      "detail": "Authentication credentials were not provided."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Kredensial valid tetapi tidak dapat menulis profil Pengguna untuk aplikasi ini.",
            "content": {
              "application/json": {
                "examples": {
                  "Forbidden": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Tidak ada Pengguna untuk `didit_internal_id` tersebut dalam aplikasi.",
            "content": {
              "application/json": {
                "examples": {
                  "Not found": {
                    "value": {
                      "detail": "Not found."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Batas laju terlampaui; lakukan back off dan coba lagi.",
            "content": {
              "application/json": {
                "examples": {
                  "Rate limited": {
                    "value": {
                      "detail": "Request was throttled. Expected available in 30 seconds."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/session/{sessionId}/update-data/": {
      "patch": {
        "summary": "Perbarui data KYC yang diekstrak dari dokumen identitas pada sesi verifikasi",
        "description": "Koreksi kolom identitas yang diekstrak (OCR / NFC) dari dokumen ID pengguna — nama, tanggal, nomor dokumen yang salah dibaca, dan sebagainya — setelah verifikasi selesai. Pemanggil umum adalah analis kepatuhan yang bekerja dari back office Anda sendiri, atau tugas rekonsiliasi otomatis. Setiap kolom dalam body bersifat opsional: hanya kunci yang Anda kirim yang akan ditulis, yang lainnya dibiarkan tanpa perubahan (semantik `PATCH`).\n\nSesi harus milik aplikasi Anda dan berada dalam status `Approved`, `Declined`, `In Review`, atau `Kyc Expired`. Sesi dalam status lain apa pun (misalnya masih `In Progress`) mengembalikan `404` dengan `\"No Session matches the given query.\"` — berbeda dari `\"Not found.\"` yang dikembalikan untuk `sessionId` yang tidak dikenal atau telah dihapus. Sesi juga harus memuat catatan verifikasi identitas (KYC): sesi yang alur kerjanya tidak pernah menjalankan langkah verifikasi identitas mengembalikan `404` (`\"The session does not have a KYC.\"`). Untuk alur kerja graf dengan beberapa langkah verifikasi identitas, targetkan langkah tertentu dengan `node_id` (parameter query atau kolom body); jika diabaikan, catatan KYC terbaru yang akan di-patch.\n\nDua kolom turunan dihitung ulang pada setiap panggilan: `full_name` (dari `first_name` + `last_name`) dan `issuing_state_name` (dari `issuing_state`). Jika teks bebas `address` berubah, server juga dapat melakukan geocoding ulang dan menyegarkan `parsed_address` (dilewati untuk sesi sandbox). `extra_fields` dan `parsed_address` digabungkan kunci per kunci alih-alih diganti — lihat deskripsi per kolom untuk semantik `null`-untuk-menghapus.\n\nMengirimkan setidaknya satu kolom valid akan memicu [webhook](/id/integration/webhooks) `data.updated` (pemicu `manual_review`) — bahkan ketika nilai yang dikirimkan sama dengan nilai yang tersimpan. Saat nilai benar-benar berubah, entri aktivitas `KYC_DATA_UPDATED` yang mencatat kolom yang diubah beserta nilai sebelumnya dan nilai baru akan ditambahkan ke `reviews` sesi, terlihat di [Dapatkan Keputusan](#get-/v3/session/-sessionId-/decision/) dan linimasa aktivitas konsol. Status dan keputusan sesi **tidak** dievaluasi ulang — gunakan [Perbarui Status](#patch-/v3/session/-sessionId-/update-status/) untuk mengubah hasilnya. Body JSON kosong (`{}`) diterima dan hanya mengembalikan data KYC saat ini tanpa memicu webhook.\n\nMenerima kunci API atau token pengguna konsol; bagaimanapun kredensial memerlukan izin `write:sessions`. Kegagalan autentikasi maupun izin sama-sama mengembalikan `403` — API ini tidak pernah merespons `401`. Perhatikan bahwa pencarian sesi berjalan sebelum pemeriksaan kredensial, sehingga `sessionId` yang tidak dikenal mengembalikan `404` meskipun kredensial tidak ada. Endpoint ini memiliki batas laju khusus sebesar 10 permintaan per menit per kunci API (permintaan tidak valid juga dihitung); kuota penulisan bersama sebesar 300 permintaan per menit juga berlaku.",
        "operationId": "patch_v3_session_update_data",
        "x-didit-sdk": {
          "resource": "sessions",
          "method": "update_data",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Sessions"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "sessionId",
            "in": "path",
            "required": true,
            "description": "UUID sesi Verifikasi Pengguna (KYC) yang data dokumen yang diekstraknya sedang Anda perbaiki. ID sesi Bisnis (KYB) tidak valid di sini — untuk data perusahaan, gunakan [Update KYB Company Data](#patch-/v3/session/-sessionId-/kyb/-companyUuid-/update-data/).",
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "11111111-2222-3333-4444-555555555555"
            }
          },
          {
            "name": "node_id",
            "in": "query",
            "required": false,
            "description": "Node graf alur kerja yang catatan KYC-nya akan di-patch, untuk alur kerja graf dengan beberapa langkah verifikasi identitas (juga diterima sebagai kolom badan `node_id`). Jika diabaikan, catatan KYC terbaru pada sesi tersebut yang akan di-patch. Jika tidak ada KYC untuk node yang ditentukan, panggilan akan mengembalikan `404` (`\"The session does not have a KYC for node '<node_id>'.\"`).",
            "schema": {
              "type": "string",
              "example": "feature_ocr"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "description": "Semua kolom bersifat opsional — kirim hanya yang ingin Anda ubah.",
                "properties": {
                  "document_type": {
                    "type": "string",
                    "description": "Kode jenis dokumen. Menerima kode pendek yang tercantum di enum, ditambah enam alias bentuk panjang yang dinormalisasi di sisi server sebelum validasi: `Passport` → `P`, `Identity Card` → `ID`, `Driver's License` → `DL`, `Residence Permit` → `RP`, `Health Insurance Card` → `HIC`, `Tax Card` → `TC`. Nilai lain apa pun (termasuk `PASSPORT` dalam huruf besar) mengembalikan `400`.",
                    "enum": [
                      "P",
                      "DL",
                      "ID",
                      "RP",
                      "SSC",
                      "HIC",
                      "WP",
                      "TC",
                      "VISA",
                      "PSC",
                      "BC",
                      "OTHER"
                    ],
                    "nullable": true,
                    "example": "P"
                  },
                  "document_subtype": {
                    "type": "string",
                    "maxLength": 128,
                    "nullable": true,
                    "description": "Subjenis dokumen dari registri dokumen, termasuk awalan wilayah jika registri membedakan varian regional."
                  },
                  "document_number": {
                    "type": "string",
                    "maxLength": 255,
                    "nullable": true,
                    "description": "Nomor dokumen seperti yang tertera pada ID.",
                    "example": "PAB123456"
                  },
                  "personal_number": {
                    "type": "string",
                    "maxLength": 255,
                    "nullable": true,
                    "description": "Nomor identifikasi pribadi / nasional jika dokumen memuatnya (misalnya, DNI Spanyol pada paspor).",
                    "example": "99999999R"
                  },
                  "date_of_birth": {
                    "type": "string",
                    "format": "date",
                    "nullable": true,
                    "description": "Tanggal lahir dalam format `YYYY-MM-DD`. Format lainnya mengembalikan `400`.",
                    "example": "1980-01-01"
                  },
                  "date_of_issue": {
                    "type": "string",
                    "format": "date",
                    "nullable": true,
                    "description": "Tanggal penerbitan dokumen dalam format `YYYY-MM-DD`."
                  },
                  "expiration_date": {
                    "type": "string",
                    "format": "date",
                    "nullable": true,
                    "description": "Tanggal kedaluwarsa dokumen dalam `YYYY-MM-DD`."
                  },
                  "issuing_state": {
                    "type": "string",
                    "nullable": true,
                    "description": "Negara penerbit sebagai kode ISO 3166-1 alpha-3. Tidak peka huruf besar/kecil (`esp` disimpan sebagai `ESP`); `issuing_state_name` yang dapat dibaca manusia yang ditampilkan di [Dapatkan Keputusan](#get-/v3/session/-sessionId-/decision/) dihitung ulang dari nilai ini. Kode yang tidak valid mengembalikan `400`.",
                    "example": "ESP"
                  },
                  "first_name": {
                    "type": "string",
                    "maxLength": 255,
                    "nullable": true,
                    "description": "Nama depan. `full_name` yang tersimpan dihitung ulang sebagai `first_name + ' ' + last_name` pada setiap panggilan ke endpoint ini.",
                    "example": "Carmen"
                  },
                  "last_name": {
                    "type": "string",
                    "maxLength": 255,
                    "nullable": true,
                    "description": "Nama keluarga. Juga mengisi `full_name` yang dihitung ulang.",
                    "example": "Espanola Espanola"
                  },
                  "gender": {
                    "type": "string",
                    "enum": [
                      "M",
                      "F",
                      "U"
                    ],
                    "nullable": true,
                    "description": "Jenis kelamin sebagaimana tercetak pada dokumen: `M` (laki-laki), `F` (perempuan), atau `U` (tidak diketahui). Nilai lainnya — termasuk `X` — mengembalikan `400`."
                  },
                  "address": {
                    "type": "string",
                    "maxLength": 255,
                    "nullable": true,
                    "description": "Alamat teks bebas seperti yang tertera pada dokumen. Ketika nilai ini berubah (hanya sesi non-sandbox) dan alamat terstruktur masih belum ada atau belum lengkap, server melakukan geocoding ulang secara sinkron sebelum merespons — isi respons 200 sudah mencerminkan `parsed_address` yang diperbarui. Geocoding ulang ini juga mengharuskan adanya `issuing_state` pada catatan KYC."
                  },
                  "place_of_birth": {
                    "type": "string",
                    "maxLength": 255,
                    "nullable": true,
                    "description": "Tempat lahir seperti yang tercetak pada dokumen."
                  },
                  "nationality": {
                    "type": "string",
                    "maxLength": 32,
                    "nullable": true,
                    "description": "Kewarganegaraan seperti yang tertera pada dokumen. Teks bebas hingga 32 karakter — biasanya kode ISO 3166-1 alpha-3 (misalnya `ESP`), tetapi tidak divalidasi sebagai kode tersebut."
                  },
                  "marital_status": {
                    "type": "string",
                    "enum": [
                      "SINGLE",
                      "MARRIED",
                      "DIVORCED",
                      "WIDOWED",
                      "UNKNOWN"
                    ],
                    "description": "Status perkawinan jika dokumen mencantumkannya. Nilai lainnya mengembalikan `400`."
                  },
                  "extra_fields": {
                    "type": "object",
                    "additionalProperties": true,
                    "nullable": true,
                    "description": "Override per kunci untuk kolom tambahan spesifik dokumen (misalnya `blood_group`, `dl_categories`, `mrz_string`). Kunci digabungkan ke dalam peta override yang ada: kirim kunci beserta nilainya untuk mengaturnya, atau dengan `null` / `\"\"` untuk menghapus kunci tersebut dari tampilan gabungan. Kirim seluruh kolom sebagai `null` untuk menghapus semua override yang diterapkan sebelumnya. Harus berupa objek JSON, jika tidak akan menghasilkan `400`. Respons selalu mengembalikan tampilan gabungan (nilai hasil ekstraksi OCR dengan override Anda yang telah diterapkan)."
                  },
                  "parsed_address": {
                    "type": "object",
                    "nullable": true,
                    "description": "Alamat terstruktur. Hanya kunci bersarang berikut yang diterima: `address_type`, `city`, `region`, `street_1`, `street_2`, `postal_code`, `country` — kunci lainnya akan mengembalikan `400`. Semantik per kunci: sebuah nilai menetapkan kunci, `null` menghapusnya. `formatted_address` dihitung ulang di sisi server dengan menggabungkan `street_1`, `street_2`, `city`, `region`, `postal_code`, dan `country` serta dikembalikan dalam respons — Anda tidak dapat menetapkannya secara langsung.",
                    "properties": {
                      "address_type": {
                        "type": "string",
                        "nullable": true,
                        "description": "Klasifikasi alamat bentuk bebas (misalnya `home`)."
                      },
                      "city": {
                        "type": "string",
                        "nullable": true,
                        "example": "Madrid"
                      },
                      "region": {
                        "type": "string",
                        "nullable": true,
                        "description": "Negara bagian / provinsi / komunitas otonom."
                      },
                      "street_1": {
                        "type": "string",
                        "nullable": true,
                        "example": "Avda de Madrid 34"
                      },
                      "street_2": {
                        "type": "string",
                        "nullable": true
                      },
                      "postal_code": {
                        "type": "string",
                        "nullable": true,
                        "example": "28013"
                      },
                      "country": {
                        "type": "string",
                        "nullable": true,
                        "description": "Kode negara ISO 3166-1 alpha-2. Input huruf kecil dinormalisasi ke huruf besar; kode alpha-3 ditolak dengan `400`.",
                        "example": "ES"
                      }
                    }
                  }
                }
              },
              "examples": {
                "Correct name and DOB": {
                  "summary": "Perbaiki kesalahan baca OCR untuk nama, tanggal lahir, dan alamat terstruktur",
                  "value": {
                    "first_name": "Carmen",
                    "last_name": "Espanola Espanola",
                    "date_of_birth": "1980-01-01",
                    "issuing_state": "ESP",
                    "marital_status": "MARRIED",
                    "extra_fields": {
                      "blood_group": "O+"
                    },
                    "parsed_address": {
                      "street_1": "Avda de Madrid 34",
                      "city": "Madrid",
                      "postal_code": "28013",
                      "country": "ES"
                    }
                  }
                },
                "Remove an extra field": {
                  "summary": "Hapus satu kunci kolom tambahan, simpan sisanya",
                  "value": {
                    "extra_fields": {
                      "blood_group": null
                    }
                  }
                },
                "Long-form document type": {
                  "summary": "Alias bentuk panjang dinormalisasi ke kode pendek (di sini P)",
                  "value": {
                    "document_type": "Passport"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Data KYC diperbarui. Mengembalikan **rekaman KYC saat ini yang lengkap** (setiap kolom yang dapat diperbarui beserta nilai tersimpannya, ditambah `extra_fields` yang digabungkan dan `parsed_address` saat ini) — bukan hanya kolom yang Anda kirimkan. Webhook `data.updated` terpicu ketika setidaknya satu kolom yang valid ada di dalam payload.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "document_type": {
                      "type": "string",
                      "description": "Kode jenis dokumen. Menerima kode pendek yang tercantum di enum, ditambah enam alias bentuk panjang yang dinormalisasi di sisi server sebelum validasi: `Passport` → `P`, `Identity Card` → `ID`, `Driver's License` → `DL`, `Residence Permit` → `RP`, `Health Insurance Card` → `HIC`, `Tax Card` → `TC`. Nilai lain apa pun (termasuk `PASSPORT` dalam huruf besar) mengembalikan `400`.",
                      "enum": [
                        "P",
                        "DL",
                        "ID",
                        "RP",
                        "SSC",
                        "HIC",
                        "WP",
                        "TC",
                        "VISA",
                        "PSC",
                        "BC",
                        "OTHER"
                      ],
                      "nullable": true,
                      "example": "P"
                    },
                    "document_subtype": {
                      "type": "string",
                      "maxLength": 128,
                      "nullable": true,
                      "description": "Subjenis dokumen dari registri dokumen, termasuk awalan wilayah jika registri membedakan varian regional."
                    },
                    "document_number": {
                      "type": "string",
                      "maxLength": 255,
                      "nullable": true,
                      "description": "Nomor dokumen seperti yang tertera pada ID.",
                      "example": "PAB123456"
                    },
                    "personal_number": {
                      "type": "string",
                      "maxLength": 255,
                      "nullable": true,
                      "description": "Nomor identifikasi pribadi / nasional jika dokumen memuatnya (misalnya, DNI Spanyol pada paspor).",
                      "example": "99999999R"
                    },
                    "date_of_birth": {
                      "type": "string",
                      "format": "date",
                      "nullable": true,
                      "description": "Tanggal lahir dalam format `YYYY-MM-DD`. Format lainnya mengembalikan `400`.",
                      "example": "1980-01-01"
                    },
                    "date_of_issue": {
                      "type": "string",
                      "format": "date",
                      "nullable": true,
                      "description": "Tanggal penerbitan dokumen dalam format `YYYY-MM-DD`."
                    },
                    "expiration_date": {
                      "type": "string",
                      "format": "date",
                      "nullable": true,
                      "description": "Tanggal kedaluwarsa dokumen dalam `YYYY-MM-DD`."
                    },
                    "issuing_state": {
                      "type": "string",
                      "nullable": true,
                      "description": "Negara penerbit sebagai kode ISO 3166-1 alpha-3. Tidak peka huruf besar/kecil (`esp` disimpan sebagai `ESP`); `issuing_state_name` yang dapat dibaca manusia yang ditampilkan di [Dapatkan Keputusan](#get-/v3/session/-sessionId-/decision/) dihitung ulang dari nilai ini. Kode yang tidak valid mengembalikan `400`.",
                      "example": "ESP"
                    },
                    "first_name": {
                      "type": "string",
                      "maxLength": 255,
                      "nullable": true,
                      "description": "Nama depan. `full_name` yang tersimpan dihitung ulang sebagai `first_name + ' ' + last_name` pada setiap panggilan ke endpoint ini.",
                      "example": "Carmen"
                    },
                    "last_name": {
                      "type": "string",
                      "maxLength": 255,
                      "nullable": true,
                      "description": "Nama keluarga. Juga mengisi `full_name` yang dihitung ulang.",
                      "example": "Espanola Espanola"
                    },
                    "gender": {
                      "type": "string",
                      "enum": [
                        "M",
                        "F",
                        "U"
                      ],
                      "nullable": true,
                      "description": "Jenis kelamin sebagaimana tercetak pada dokumen: `M` (laki-laki), `F` (perempuan), atau `U` (tidak diketahui). Nilai lainnya — termasuk `X` — mengembalikan `400`."
                    },
                    "address": {
                      "type": "string",
                      "maxLength": 255,
                      "nullable": true,
                      "description": "Alamat teks bebas seperti yang tertera pada dokumen. Ketika nilai ini berubah (hanya sesi non-sandbox) dan alamat terstruktur masih belum ada atau belum lengkap, server melakukan geocoding ulang di latar belakang pada permintaan yang sama dan dapat menimpa `parsed_address` dengan hasil geocoder."
                    },
                    "place_of_birth": {
                      "type": "string",
                      "maxLength": 255,
                      "nullable": true,
                      "description": "Tempat lahir seperti yang tercetak pada dokumen."
                    },
                    "nationality": {
                      "type": "string",
                      "maxLength": 32,
                      "nullable": true,
                      "description": "Kewarganegaraan seperti yang tertera pada dokumen. Teks bebas hingga 32 karakter — biasanya kode ISO 3166-1 alpha-3 (misalnya `ESP`), tetapi tidak divalidasi sebagai kode tersebut."
                    },
                    "marital_status": {
                      "type": "string",
                      "enum": [
                        "SINGLE",
                        "MARRIED",
                        "DIVORCED",
                        "WIDOWED",
                        "UNKNOWN"
                      ],
                      "description": "Status perkawinan jika dokumen mencantumkannya. Nilai lainnya mengembalikan `400`."
                    },
                    "extra_fields": {
                      "type": "object",
                      "additionalProperties": true,
                      "nullable": true,
                      "description": "Tampilan gabungan dari kolom tambahan dokumen: nilai yang diekstraksi OCR dengan semua penggantian operator yang diterapkan. Kunci yang dihapus melalui penggantian `null` tidak ada dalam peta ini."
                    },
                    "parsed_address": {
                      "type": "object",
                      "nullable": true,
                      "description": "Alamat terstruktur saat ini (dengan kunci pembukuan internal dihapus), atau `null` jika tidak ada. Mencakup `formatted_address` yang dihitung ulang bersama tujuh kunci yang dapat diedit.",
                      "properties": {
                        "address_type": {
                          "type": "string",
                          "nullable": true,
                          "description": "Klasifikasi alamat bentuk bebas (misalnya `home`)."
                        },
                        "city": {
                          "type": "string",
                          "nullable": true,
                          "example": "Madrid"
                        },
                        "region": {
                          "type": "string",
                          "nullable": true,
                          "description": "Negara bagian / provinsi / komunitas otonom."
                        },
                        "street_1": {
                          "type": "string",
                          "nullable": true,
                          "example": "Avda de Madrid 34"
                        },
                        "street_2": {
                          "type": "string",
                          "nullable": true
                        },
                        "postal_code": {
                          "type": "string",
                          "nullable": true,
                          "example": "28013"
                        },
                        "country": {
                          "type": "string",
                          "nullable": true,
                          "description": "Kode negara ISO 3166-1 alpha-2. Input huruf kecil dinormalisasi ke huruf besar; kode alpha-3 ditolak dengan `400`.",
                          "example": "ES"
                        },
                        "formatted_address": {
                          "type": "string",
                          "nullable": true,
                          "description": "Bentuk gabungan yang dapat dibaca manusia dari alamat terstruktur. Dihitung ulang di sisi server setelah setiap pengeditan `parsed_address`.",
                          "example": "Avda de Madrid 34, Madrid, 28013, ES"
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "Updated KYC": {
                    "summary": "Catatan KYC lengkap setelah koreksi",
                    "value": {
                      "document_type": "P",
                      "document_subtype": null,
                      "document_number": "PAB123456",
                      "personal_number": "99999999R",
                      "date_of_birth": "1980-01-01",
                      "date_of_issue": "2021-02-09",
                      "expiration_date": "2031-02-08",
                      "issuing_state": "ESP",
                      "first_name": "Carmen",
                      "last_name": "Espanola Espanola",
                      "gender": "F",
                      "address": "AVDA DE MADRID 34, MADRID, MADRID 28013",
                      "place_of_birth": "MADRID",
                      "nationality": "ESP",
                      "marital_status": "MARRIED",
                      "extra_fields": {
                        "mrz_string": "P<ESPESPANOLA<<CARMEN<<<<<",
                        "blood_group": "O+"
                      },
                      "parsed_address": {
                        "city": "Madrid",
                        "street_1": "Avda de Madrid 34",
                        "postal_code": "28013",
                        "country": "ES",
                        "formatted_address": "Avda de Madrid 34, Madrid, 28013, ES"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Kesalahan validasi. Kesalahan kolom diterima sebagai `{\"<field>\": [\"<message>\"]}`; kesalahan pada kunci bertingkat `parsed_address` / `extra_fields` menggunakan nilai objek: `{\"parsed_address\": {\"<key>\": \"<message>\"}}`.",
            "content": {
              "application/json": {
                "examples": {
                  "Invalid gender": {
                    "summary": "gender harus berupa M, F, atau U",
                    "value": {
                      "gender": [
                        "\"X\" is not a valid choice."
                      ]
                    }
                  },
                  "Invalid document type": {
                    "summary": "Bukan kode pendek atau alias bentuk panjang",
                    "value": {
                      "document_type": [
                        "\"PASSPORT\" is not a valid choice."
                      ]
                    }
                  },
                  "Invalid issuing state": {
                    "summary": "issuing_state bukan ISO 3166-1 alpha-3",
                    "value": {
                      "issuing_state": [
                        "Invalid ISO 3166-1 alpha-3 country code for issuing_state."
                      ]
                    }
                  },
                  "Invalid marital status": {
                    "summary": "marital_status tidak ada dalam enum",
                    "value": {
                      "marital_status": [
                        "\"ENGAGED\" is not a valid choice."
                      ]
                    }
                  },
                  "Bad date format": {
                    "summary": "Tanggal harus berformat YYYY-MM-DD",
                    "value": {
                      "date_of_birth": [
                        "Date has wrong format. Use one of these formats instead: YYYY-MM-DD."
                      ]
                    }
                  },
                  "Unsupported parsed_address key": {
                    "summary": "Hanya tujuh kunci yang terdokumentasi yang diizinkan",
                    "value": {
                      "parsed_address": {
                        "zipcode": "Unsupported key. Allowed keys: address_type, city, region, street_1, street_2, postal_code, country"
                      }
                    }
                  },
                  "Invalid parsed_address country": {
                    "summary": "Negara bersarang harus berupa alpha-2, bukan alpha-3",
                    "value": {
                      "parsed_address": {
                        "country": "Invalid ISO 3166-1 alpha-2 country code."
                      }
                    }
                  },
                  "extra_fields not an object": {
                    "summary": "extra_fields harus berupa objek JSON",
                    "value": {
                      "extra_fields": [
                        "This field must be a JSON object."
                      ]
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Kredensial tidak ada atau izin tidak mencukupi. Kunci yang tidak ada mengembalikan `403`; kunci yang salah, dicabut, atau kedaluwarsa mengembalikan `401`.",
            "content": {
              "application/json": {
                "examples": {
                  "Invalid Credentials": {
                    "summary": "x-api-key tidak ada atau tidak valid",
                    "value": {
                      "detail": "Authentication credentials were not provided or are invalid."
                    }
                  },
                  "Missing Privilege": {
                    "summary": "Kredensial tidak memiliki write:sessions",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Sesi tidak dikenal, sesi dalam status tidak dapat diedit, atau tidak ada rekaman KYC untuk di-patch. Setiap kasus memiliki pesan `detail` yang berbeda (lihat contoh). Pencarian sesi yang tidak dikenal dijalankan sebelum pemeriksaan kredensial.",
            "content": {
              "application/json": {
                "examples": {
                  "Unknown session": {
                    "summary": "Tidak ada sesi dengan ID ini di aplikasi Anda (atau telah dihapus)",
                    "value": {
                      "detail": "Not found."
                    }
                  },
                  "Wrong session state": {
                    "summary": "Sesi ada tetapi tidak Approved / Declined / In Review / Kyc Expired",
                    "value": {
                      "detail": "No Session matches the given query."
                    }
                  },
                  "No KYC record": {
                    "summary": "Alur kerja tidak pernah menjalankan langkah Verifikasi Identitas",
                    "value": {
                      "detail": "The session does not have a KYC."
                    }
                  },
                  "No KYC for node": {
                    "summary": "node_id diberikan tetapi tidak ada KYC yang ada untuknya",
                    "value": {
                      "detail": "The session does not have a KYC for node 'feature_missing'."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Batas laju khusus terlampaui — 10 pembaruan data KYC per menit per kunci API (permintaan yang ditolak diperhitungkan ke dalam kuota). Kuota tulis bersama 300/menit juga dapat terpicu dengan pesannya sendiri. Periksa header respons `Retry-After` dan `X-RateLimit-*` sebelum mencoba lagi.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Rate limited": {
                    "summary": "Anggaran pembaruan KYC habis",
                    "value": {
                      "detail": "Session KYC data update rate limit exceeded. You can make up to 10 requests per minute."
                    }
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X PATCH \\\n  https://verification.didit.me/v3/session/11111111-2222-3333-4444-555555555555/update-data/ \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"first_name\": \"Carmen\",\n    \"last_name\": \"Espanola Espanola\",\n    \"date_of_birth\": \"1980-01-01\",\n    \"issuing_state\": \"ESP\",\n    \"parsed_address\": {\n      \"street_1\": \"Avda de Madrid 34\",\n      \"city\": \"Madrid\",\n      \"postal_code\": \"28013\",\n      \"country\": \"ES\"\n    }\n  }'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.update_data(\n    \"11111111-2222-3333-4444-555555555555\",\n    date_of_birth=\"1980-01-01\",\n    issuing_state=\"ESP\",\n    first_name=\"Carmen\",\n    last_name=\"Espanola Espanola\",\n    marital_status=\"MARRIED\",\n    extra_fields={\"blood_group\": \"O+\"},\n    parsed_address={\n        \"city\": \"Madrid\",\n        \"street_1\": \"Avda de Madrid 34\",\n        \"postal_code\": \"28013\",\n        \"country\": \"ES\",\n    },\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.updateData(\"11111111-2222-3333-4444-555555555555\", {\n  date_of_birth: \"1980-01-01\",\n  issuing_state: \"ESP\",\n  first_name: \"Carmen\",\n  last_name: \"Espanola Espanola\",\n  marital_status: \"MARRIED\",\n  extra_fields: { blood_group: \"O+\" },\n  parsed_address: {\n    city: \"Madrid\",\n    street_1: \"Avda de Madrid 34\",\n    postal_code: \"28013\",\n    country: \"ES\",\n  },\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.UpdateData(ctx, \"11111111-2222-3333-4444-555555555555\", didit.SessionsUpdateDataParams{\n\tDateOfBirth:   didit.String(\"1980-01-01\"),\n\tIssuingState:  didit.String(\"ESP\"),\n\tFirstName:     didit.String(\"Carmen\"),\n\tLastName:      didit.String(\"Espanola Espanola\"),\n\tMaritalStatus: didit.Some(didit.SessionsUpdateDataParamsMaritalStatus(\"MARRIED\")),\n\tExtraFields:   didit.Some(map[string]any{\"blood_group\": \"O+\"}),\n\tParsedAddress: didit.Some(didit.SessionsUpdateDataParamsParsedAddress{\n\t\tCity:       didit.String(\"Madrid\"),\n\t\tStreet1:    didit.String(\"Avda de Madrid 34\"),\n\t\tPostalCode: didit.String(\"28013\"),\n\t\tCountry:    didit.String(\"ES\"),\n\t}),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.time.LocalDate;\nimport java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.SessionsUpdateDataParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().updateData(\"11111111-2222-3333-4444-555555555555\", SessionsUpdateDataParams.builder()\n        .dateOfBirth(LocalDate.parse(\"1980-01-01\"))\n        .issuingState(\"ESP\")\n        .firstName(\"Carmen\")\n        .lastName(\"Espanola Espanola\")\n        .maritalStatus(SessionsUpdateDataParams.MaritalStatus.of(\"MARRIED\"))\n        .extraFields(Map.of(\"blood_group\", \"O+\"))\n        .parsedAddress(SessionsUpdateDataParams.ParsedAddress.builder()\n                .city(\"Madrid\")\n                .street1(\"Avda de Madrid 34\")\n                .postalCode(\"28013\")\n                .country(\"ES\")\n                .build())\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->sessions->updateData('11111111-2222-3333-4444-555555555555', [\n    'date_of_birth' => '1980-01-01',\n    'issuing_state' => 'ESP',\n    'first_name' => 'Carmen',\n    'last_name' => 'Espanola Espanola',\n    'marital_status' => 'MARRIED',\n    'extra_fields' => ['blood_group' => 'O+'],\n    'parsed_address' => [\n        'city' => 'Madrid',\n        'street_1' => 'Avda de Madrid 34',\n        'postal_code' => '28013',\n        'country' => 'ES',\n    ],\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.update_data(\n  \"11111111-2222-3333-4444-555555555555\",\n  date_of_birth: \"1980-01-01\",\n  issuing_state: \"ESP\",\n  first_name: \"Carmen\",\n  last_name: \"Espanola Espanola\",\n  marital_status: \"MARRIED\",\n  extra_fields: { blood_group: \"O+\" },\n  parsed_address: {\n    city: \"Madrid\",\n    street_1: \"Avda de Madrid 34\",\n    postal_code: \"28013\",\n    country: \"ES\",\n  }\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.UpdateDataAsync(\"11111111-2222-3333-4444-555555555555\", new SessionsUpdateDataParams\n{\n    DateOfBirth = \"1980-01-01\",\n    IssuingState = \"ESP\",\n    FirstName = \"Carmen\",\n    LastName = \"Espanola Espanola\",\n    MaritalStatus = new SessionsUpdateDataParamsMaritalStatus(\"MARRIED\"),\n    ExtraFields = new Dictionary<string, object> { [\"blood_group\"] = \"O+\" },\n    ParsedAddress = new SessionsUpdateDataParamsParsedAddress\n    {\n        City = \"Madrid\",\n        Street1 = \"Avda de Madrid 34\",\n        PostalCode = \"28013\",\n        Country = \"ES\",\n    },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/session/{sessionId}/features/{nodeId}/update-status/": {
      "patch": {
        "summary": "Perbarui status fitur (langkah) individual",
        "description": "Atur status dari satu fitur (langkah) verifikasi dalam suatu sesi. Targetkan fitur berdasarkan `nodeId` graf alur kerjanya. Pada alur kerja non-graf, yang langkah-langkahnya tidak memiliki node, gunakan `default` dan teruskan juga `feature_type` untuk menentukan langkah yang Anda maksud.\n\nBerfungsi untuk sesi Verifikasi Pengguna (KYC) maupun Verifikasi Bisnis (KYB) dan setiap jenis langkah: ID/OCR, Liveness, Face Match, NFC, AML, Bukti Alamat, Telepon, Email, Validasi Database, Kuesioner, serta pemeriksaan registri / dokumen / pihak kunci KYB. Endpoint ini **tidak** tersedia untuk sesi API mandiri (`session_type = API`).\n\n`new_status` harus salah satu dari `Approved`, `Declined`, atau `In Review`, dan harus berbeda dari status fitur saat ini.\n\n**Kapan override berlaku.** Tanpa `defer_until_flow_finishes` (atau dengan `false`), override akan langsung diterapkan, seperti biasanya; ketika orang tersebut masih berada dalam alur, tindakan ini dicatat sebagai `forced`. Dengan `defer_until_flow_finishes: true` saat orang tersebut masih berada dalam alur (sesi berstatus `Not Started`, `In Progress`, atau `Resubmitted` dan belum selesai), override disimpan sebagai `pending_until_flow_finishes` dan berlaku ketika alur selesai, setelah alur mencapai keputusannya sendiri. Pada sesi yang alurnya sudah berakhir, override akan langsung berlaku dalam kedua kondisi tersebut. Override yang sedang menunggu akan dibatalkan jika orang tersebut mengulangi langkahnya sebelum selesai, jika override yang lebih baru pada pemeriksaan yang sama menggantikannya, jika sesi meninggalkan alur dalam keadaan belum selesai (ditinggalkan, kedaluwarsa, atau diputuskan di tengah alur), atau ketika Anda membatalkannya dengan `POST /v3/session/{sessionId}/features/overrides/{overrideId}/cancel/`. Dapatkan daftar override suatu sesi dengan `GET /v3/session/{sessionId}/features/overrides/`.\n\n**Pengaruh pada sesi.** Sesi yang sudah memiliki keputusan akan tetap mempertahankannya: hanya pemeriksaannya yang berubah. Ketika sesi belum memiliki keputusan dan alur kerjanya sedang menunggu langkah ini secara tepat, penerapan override akan menyelesaikan langkah tersebut: alur kerja berlanjut, langkah-langkah berikutnya berjalan, dan node status dapat menetapkan keputusan sesi serta memicu `status.updated`.\n\n**Webhook dan aktivitas.** Webhook `data.updated` dipicu ketika override diterapkan (langsung, atau ketika alur selesai), tidak pernah saat sedang menunggu atau saat dibatalkan. Setiap override dicatat dalam aktivitas sesi sebagai `FEATURE_OVERRIDE_PENDING`, `FEATURE_OVERRIDE_APPLIED`, atau `FEATURE_OVERRIDE_CANCELLED`, beserta pihak yang melakukannya; entri permintaan menyertakan `comment` Anda.\n\nLakukan autentikasi dengan kunci API Anda (`x-api-key`) atau header otorisasi pengguna yang memuat hak istimewa `write:sessions`; kunci API dengan cakupan (scoped) memerlukan akses tulis ke keputusan.",
        "operationId": "patch_v3_session_update_feature_status",
        "x-didit-sdk": {
          "resource": "sessions",
          "method": "update_feature_status",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Sessions"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "in": "path",
            "name": "sessionId",
            "required": true,
            "description": "UUID sesi verifikasi. Menerima ID sesi pengguna (KYC) dan bisnis (KYB) — layanan mencari ID tersebut di kedua jenis sesi.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "11111111-2222-3333-4444-555555555555"
            }
          },
          {
            "in": "path",
            "name": "nodeId",
            "required": true,
            "description": "ID node graf alur kerja dari fitur yang akan diperbarui (misalnya `feature_ocr_1`). Gunakan nilai harfiah `default` untuk alur kerja non-graf (satu langkah) di mana fitur tersebut tidak memiliki ID node.",
            "schema": {
              "type": "string",
              "example": "feature_ocr_1"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "new_status"
                ],
                "properties": {
                  "new_status": {
                    "type": "string",
                    "description": "Status target untuk fitur ini. Harus berbeda dari nilai saat ini.",
                    "enum": [
                      "Approved",
                      "Declined",
                      "In Review"
                    ],
                    "example": "Approved"
                  },
                  "comment": {
                    "type": "string",
                    "description": "Catatan teks bebas opsional yang dicatat pada jejak peninjauan sesi untuk perubahan fitur ini.",
                    "example": "Document manually verified by compliance."
                  },
                  "feature_type": {
                    "type": "string",
                    "enum": [
                      "ID_VERIFICATION",
                      "OCR",
                      "OCR_BACK",
                      "NFC",
                      "LIVENESS",
                      "FACE",
                      "AGE_ESTIMATION",
                      "AGE_VERIFICATION",
                      "FACE_SEARCH",
                      "FACE_MATCH",
                      "IP_ANALYSIS",
                      "AML",
                      "PHONE",
                      "PHONE_VERIFICATION",
                      "EMAIL",
                      "EMAIL_VERIFICATION",
                      "POA",
                      "PROOF_OF_ADDRESS",
                      "DATABASE_VALIDATION",
                      "DATA_VALIDATION",
                      "QUESTIONNAIRE",
                      "DOCUMENT_AI",
                      "KYB_REGISTRY",
                      "KYB_DOCUMENTS",
                      "KYB_KEY_PEOPLE",
                      "BANK_VERIFICATION",
                      "GEOLOCATION"
                    ],
                    "description": "Jenis langkah mana yang ditargetkan. Diperlukan pada alur kerja non-graf (`nodeId` = `default`), di mana setiap langkah tidak berbagi node; jika tidak, bersifat opsional. Nilai yang tidak dikenal akan mengembalikan `400`.",
                    "example": "LIVENESS"
                  },
                  "defer_until_flow_finishes": {
                    "type": "boolean",
                    "default": false,
                    "description": "Saat orang tersebut masih berada dalam alur, simpan override sebagai `pending_until_flow_finishes` dan terapkan saat alur selesai, alih-alih langsung diterapkan. Jika tidak dicantumkan atau `false`, override langsung diterapkan. Pada sesi yang alurnya sudah berakhir, override langsung diterapkan dalam kondisi apa pun.",
                    "example": false
                  }
                }
              },
              "examples": {
                "Apply Now": {
                  "summary": "Setujui langkah ID sekaligus",
                  "value": {
                    "new_status": "Approved",
                    "comment": "Document manually verified by compliance."
                  }
                },
                "Wait For The Flow": {
                  "summary": "Setujui langkah liveness setelah orang tersebut menyelesaikan alur",
                  "value": {
                    "new_status": "Approved",
                    "comment": "Liveness retried with a reviewer present.",
                    "defer_until_flow_finishes": true
                  }
                },
                "Non-graph Workflow": {
                  "summary": "Menargetkan langkah liveness dari alur kerja tanpa node (nodeId = default)",
                  "value": {
                    "new_status": "In Review",
                    "feature_type": "LIVENESS"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Penggantian telah dicatat. `new_status` adalah status pemeriksaan yang tersimpan: status yang diminta setelah penggantian diterapkan, atau status yang tidak berubah saat menunggu alur selesai. `override` menyatakan apa yang terjadi.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "session_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "node_id": {
                      "type": "string",
                      "nullable": true,
                      "description": "Node alur kerja langkah yang diperbarui, atau `null` untuk langkah tanpa node (jalur `default` dalam alur kerja non-graf).",
                      "example": "feature_ocr_1"
                    },
                    "feature_type": {
                      "type": "string",
                      "description": "Nama model dari fitur yang diperbarui (misalnya `KYC`, `Face`, `FaceMatch`, `AML`, `POA`).",
                      "example": "KYC"
                    },
                    "new_status": {
                      "type": "string",
                      "description": "Status tersimpan dari pemeriksaan: status yang diminta setelah override diterapkan, atau yang tidak berubah saat override menunggu alur selesai.",
                      "example": "Approved"
                    },
                    "override": {
                      "$ref": "#/components/schemas/FeatureStatusOverride"
                    }
                  },
                  "required": [
                    "session_id",
                    "node_id",
                    "feature_type",
                    "new_status",
                    "override"
                  ]
                },
                "examples": {
                  "Applied": {
                    "summary": "Penggantian segera diterapkan",
                    "value": {
                      "session_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "node_id": "feature_ocr_1",
                      "feature_type": "KYC",
                      "new_status": "Approved",
                      "override": {
                        "id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
                        "node_id": "feature_ocr_1",
                        "feature_type": "",
                        "feature_model": "KYC",
                        "previous_status": "In Review",
                        "new_status": "Approved",
                        "state": "applied",
                        "forced": false,
                        "reason": "Document manually verified by compliance.",
                        "requested_by": {
                          "email": "reviewer@example.com",
                          "name": "Alex Reviewer",
                          "type": "CONSOLE_USER"
                        },
                        "requested_at": "2026-10-13T09:15:00Z",
                        "applied_at": "2026-10-13T09:15:00Z",
                        "cancelled_at": null,
                        "cancel_reason": null
                      }
                    }
                  },
                  "Waiting For The Flow": {
                    "summary": "defer_until_flow_finishes saat orang tersebut masih berada dalam alur",
                    "value": {
                      "session_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "node_id": "feature_liveness_1",
                      "feature_type": "Face",
                      "new_status": "Declined",
                      "override": {
                        "id": "9b2f4c1e-8d3a-4e5f-a6b7-c8d9e0f1a2b3",
                        "node_id": "feature_liveness_1",
                        "feature_type": "",
                        "feature_model": "Face",
                        "previous_status": "Declined",
                        "new_status": "Approved",
                        "state": "pending_until_flow_finishes",
                        "forced": false,
                        "reason": "Liveness retried with a reviewer present.",
                        "requested_by": {
                          "email": "reviewer@example.com",
                          "name": "Alex Reviewer",
                          "type": "CONSOLE_USER"
                        },
                        "requested_at": "2026-10-13T09:15:00Z",
                        "applied_at": null,
                        "cancelled_at": null,
                        "cancel_reason": null
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Kesalahan validasi. Dikembalikan ketika `new_status` tidak valid atau tidak berubah, ketika `feature_type` tidak diketahui, atau ketika sesi tersebut adalah sesi API mandiri.",
            "content": {
              "application/json": {
                "examples": {
                  "Same Status": {
                    "summary": "new_status sama dengan status saat ini",
                    "value": {
                      "new_status": [
                        "The new status is the same as the current status."
                      ]
                    }
                  },
                  "API Session": {
                    "summary": "Status fitur tidak dapat diubah pada sesi API mandiri",
                    "value": [
                      "Cannot change feature status for API sessions."
                    ]
                  },
                  "Unknown feature_type": {
                    "summary": "feature_type bukan tipe langkah yang dikenal",
                    "value": {
                      "feature_type": [
                        "Unknown feature_type 'SELFIE'."
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Kunci API dengan cakupan terbatas telah kedaluwarsa.",
            "content": {
              "application/json": {
                "examples": {
                  "Expired API Key": {
                    "summary": "Kunci API ber-scope melewati tanggal kedaluwarsanya",
                    "value": {
                      "detail": "This API key has expired."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Kredensial tidak ada atau izin tidak mencukupi.",
            "content": {
              "application/json": {
                "examples": {
                  "Invalid Credentials": {
                    "summary": "x-api-key tidak ada atau tidak valid",
                    "value": {
                      "detail": "Authentication credentials were not provided or are invalid."
                    }
                  },
                  "Missing Privilege": {
                    "summary": "Kunci API tidak memiliki write:sessions",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Scoped Key Without Access": {
                    "summary": "Kunci API ber-scope tanpa akses tulis ke keputusan",
                    "value": {
                      "detail": "This API key has no write access to decisions."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Sesi tidak ditemukan, atau tidak memiliki fitur dengan `nodeId` yang diberikan.",
            "content": {
              "application/json": {
                "examples": {
                  "Session Not Found": {
                    "summary": "session_id tidak dikenal",
                    "value": {
                      "detail": "Session not found."
                    }
                  },
                  "Feature Not Found": {
                    "summary": "Tidak ada fitur untuk node_id ini",
                    "value": {
                      "detail": "No feature found with node_id 'feature_ocr_1' in this session."
                    }
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X PATCH \\\n  https://verification.didit.me/v3/session/11111111-2222-3333-4444-555555555555/features/feature_ocr_1/update-status/ \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"new_status\": \"Approved\",\n    \"comment\": \"Document manually verified by compliance.\"\n  }'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.update_feature_status(\n    \"11111111-2222-3333-4444-555555555555\",\n    \"feature_ocr_1\",\n    new_status=\"Approved\",\n    comment=\"Document manually verified by compliance.\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.updateFeatureStatus(\n  \"11111111-2222-3333-4444-555555555555\",\n  \"feature_ocr_1\",\n  {\n    new_status: \"Approved\",\n    comment: \"Document manually verified by compliance.\",\n  },\n);\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.UpdateFeatureStatus(ctx, \"11111111-2222-3333-4444-555555555555\", \"feature_ocr_1\", didit.SessionsUpdateFeatureStatusParams{\n\tNewStatus: \"Approved\",\n\tComment:   didit.String(\"Document manually verified by compliance.\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.SessionsUpdateFeatureStatusParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().updateFeatureStatus(\"11111111-2222-3333-4444-555555555555\", \"feature_ocr_1\", SessionsUpdateFeatureStatusParams.builder()\n        .newStatus(SessionsUpdateFeatureStatusParams.NewStatus.of(\"Approved\"))\n        .comment(\"Document manually verified by compliance.\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->sessions->updateFeatureStatus('11111111-2222-3333-4444-555555555555', 'feature_ocr_1', [\n    'new_status' => 'Approved',\n    'comment' => 'Document manually verified by compliance.',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.update_feature_status(\n  \"11111111-2222-3333-4444-555555555555\",\n  \"feature_ocr_1\",\n  new_status: \"Approved\",\n  comment: \"Document manually verified by compliance.\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.UpdateFeatureStatusAsync(\"11111111-2222-3333-4444-555555555555\", \"feature_ocr_1\", new SessionsUpdateFeatureStatusParams\n{\n    NewStatus = \"Approved\",\n    Comment = \"Document manually verified by compliance.\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/session/{sessionId}/update-aml-hit-status/": {
      "patch": {
        "summary": "Perbarui status peninjauan hit AML",
        "description": "Tetapkan status peninjauan untuk **satu hit AML** (potensi kecocokan sanksi / PEP / daftar pantauan / media negatif) yang dikembalikan oleh Skrining AML, tanpa mengubah keputusan sesi secara keseluruhan. Identifikasi hit berdasarkan `hit_id`-nya (`id` dari sebuah entri dalam array `hits` pada pemeriksaan AML — lihat keputusan sesi). ID hit yang dikembalikan dalam format sebelumnya masih diterima; respons selalu menamai hit berdasarkan `id` saat ini.\n\n`review_status` adalah salah satu dari `Unreviewed`, `Confirmed Match`, `False Positive`, atau `Inconclusive`. Keputusan peninjau dipertahankan di seluruh pembaruan pemantauan berkelanjutan, sehingga hit yang Anda tandai `False Positive` tetap seperti itu saat penyedia melakukan skrining ulang.\n\nPanggilan yang berhasil memicu webhook `data.updated` dan menambahkan entri aktivitas (dengan atribusi pelaku) ke jejak peninjauan sesi. Untuk alur kerja graf dengan beberapa pemeriksaan AML, teruskan `node_id` untuk menargetkan pemeriksaan tertentu.\n\nLakukan autentikasi dengan kunci API Anda (`x-api-key`) atau header otorisasi pengguna — keduanya harus memiliki hak istimewa `write:sessions`.",
        "operationId": "patch_v3_session_update_aml_hit_status",
        "x-didit-sdk": {
          "resource": "sessions",
          "method": "update_aml_hit_status",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Sessions"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "in": "path",
            "name": "sessionId",
            "required": true,
            "description": "UUID sesi verifikasi. Menerima ID sesi pengguna (KYC) dan bisnis (KYB) — layanan mencari ID tersebut di kedua jenis sesi.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "11111111-2222-3333-4444-555555555555"
            }
          },
          {
            "in": "query",
            "name": "node_id",
            "required": false,
            "description": "ID node graf alur kerja. Hanya diperlukan jika sesi memiliki beberapa pemeriksaan AML (satu per node); abaikan untuk sesi dengan AML tunggal.",
            "schema": {
              "type": "string",
              "example": "feature_aml_1"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "hit_id",
                  "review_status"
                ],
                "properties": {
                  "hit_id": {
                    "type": "string",
                    "description": "`id` dari hit dalam array `hits` pemeriksaan AML (`hit_...`). ID hit yang dikembalikan dalam format sebelumnya masih diterima.",
                    "example": "hit_7c1e9a40b2d35f86e0a4c912"
                  },
                  "review_status": {
                    "type": "string",
                    "description": "Status peninjauan baru untuk temuan tersebut.",
                    "enum": [
                      "Unreviewed",
                      "Confirmed Match",
                      "False Positive",
                      "Inconclusive"
                    ],
                    "example": "False Positive"
                  },
                  "node_id": {
                    "type": "string",
                    "description": "ID node graf opsional. Gunakan ID ini (di sini atau sebagai parameter kueri) saat sesi memiliki beberapa pemeriksaan AML.",
                    "example": "feature_aml_1"
                  }
                }
              },
              "example": {
                "hit_id": "hit_7c1e9a40b2d35f86e0a4c912",
                "review_status": "False Positive"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Status peninjauan hit diperbarui.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "message",
                    "hit_id",
                    "review_status"
                  ],
                  "properties": {
                    "message": {
                      "type": "string",
                      "description": "Selalu `Hit status updated successfully`."
                    },
                    "hit_id": {
                      "type": "string",
                      "description": "`id` dari hit yang diperbarui, sebagaimana dikembalikan oleh keputusan sesi, juga saat permintaan menyebutkan hit berdasarkan id dalam format sebelumnya."
                    },
                    "review_status": {
                      "type": "string",
                      "enum": [
                        "Unreviewed",
                        "Confirmed Match",
                        "False Positive",
                        "Inconclusive"
                      ],
                      "description": "Status peninjauan yang sekarang disimpan pada hasil kecocokan."
                    }
                  }
                },
                "example": {
                  "message": "Hit status updated successfully",
                  "hit_id": "hit_7c1e9a40b2d35f86e0a4c912",
                  "review_status": "False Positive"
                }
              }
            }
          },
          "400": {
            "description": "Kesalahan validasi — `hit_id` kosong atau `review_status` bukan salah satu dari nilai yang diizinkan.",
            "content": {
              "application/json": {
                "example": {
                  "review_status": [
                    "\"Maybe\" is not a valid choice."
                  ]
                }
              }
            }
          },
          "403": {
            "description": "Kredensial tidak ada atau izin tidak mencukupi. Kunci yang tidak ada mengembalikan `403`; kunci yang salah, dicabut, atau kedaluwarsa mengembalikan `401`.",
            "content": {
              "application/json": {
                "examples": {
                  "Invalid Credentials": {
                    "summary": "x-api-key tidak ada atau tidak valid",
                    "value": {
                      "detail": "Authentication credentials were not provided or are invalid."
                    }
                  },
                  "Missing Privilege": {
                    "summary": "Kunci API tidak memiliki write:sessions",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Sesi tidak ditemukan, sesi tidak memiliki pemeriksaan AML (opsional untuk `node_id` yang diberikan), atau tidak ada kecocokan dengan `hit_id`.",
            "content": {
              "application/json": {
                "examples": {
                  "No AML Check": {
                    "summary": "Sesi tidak memiliki pemeriksaan AML",
                    "value": {
                      "detail": "The session does not have an AML check."
                    }
                  },
                  "Hit Not Found": {
                    "summary": "hit_id tidak dikenal",
                    "value": {
                      "detail": "Hit with ID 'hit_9d2e7f41c0a8b3e65d1f0c47' not found in the AML check."
                    }
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X PATCH \\\n  https://verification.didit.me/v3/session/11111111-2222-3333-4444-555555555555/update-aml-hit-status/ \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"hit_id\": \"abc123\",\n    \"review_status\": \"False Positive\"\n  }'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.update_aml_hit_status(\n    \"11111111-2222-3333-4444-555555555555\",\n    hit_id=\"hit_7c1e9a40b2d35f86e0a4c912\",\n    review_status=\"False Positive\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.updateAmlHitStatus(\"11111111-2222-3333-4444-555555555555\", {\n  hit_id: \"hit_7c1e9a40b2d35f86e0a4c912\",\n  review_status: \"False Positive\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.UpdateAMLHitStatus(ctx, \"11111111-2222-3333-4444-555555555555\", didit.SessionsUpdateAMLHitStatusParams{\n\tHitID:        \"hit_7c1e9a40b2d35f86e0a4c912\",\n\tReviewStatus: \"False Positive\",\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.SessionsUpdateAmlHitStatusParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().updateAmlHitStatus(\"11111111-2222-3333-4444-555555555555\", SessionsUpdateAmlHitStatusParams.builder()\n        .hitId(\"hit_7c1e9a40b2d35f86e0a4c912\")\n        .reviewStatus(SessionsUpdateAmlHitStatusParams.ReviewStatus.of(\"False Positive\"))\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->sessions->updateAmlHitStatus('11111111-2222-3333-4444-555555555555', [\n    'hit_id' => 'hit_7c1e9a40b2d35f86e0a4c912',\n    'review_status' => 'False Positive',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.update_aml_hit_status(\n  \"11111111-2222-3333-4444-555555555555\",\n  hit_id: \"hit_7c1e9a40b2d35f86e0a4c912\",\n  review_status: \"False Positive\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.UpdateAmlHitStatusAsync(\"11111111-2222-3333-4444-555555555555\", new SessionsUpdateAmlHitStatusParams\n{\n    HitId = \"hit_7c1e9a40b2d35f86e0a4c912\",\n    ReviewStatus = \"False Positive\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/session/{sessionId}/bulk-update-aml-hit-status/": {
      "patch": {
        "summary": "Pembaruan massal status peninjauan temuan AML",
        "description": "Perbarui status peninjauan dari **beberapa temuan AML** dalam satu panggilan. Berikan `hit_updates`, daftar pasangan `{ hit_id, review_status }`. `review_status` adalah salah satu dari `Unreviewed`, `Confirmed Match`, `False Positive`, atau `Inconclusive`.\n\nPembaruan ini bersifat semua atau tidak sama sekali: jika ada `hit_id` yang tidak ditemukan dalam pemeriksaan AML, permintaan akan mengembalikan `404` dan tidak ada temuan yang diubah. Panggilan yang berhasil akan memicu satu webhook `data.updated` dan mencatat satu entri aktivitas yang mencakup semua perubahan. Untuk alur kerja graf dengan beberapa pemeriksaan AML, teruskan `node_id` untuk menargetkan pemeriksaan tertentu.\n\nLakukan autentikasi dengan kunci API Anda (`x-api-key`) atau header otorisasi pengguna — salah satunya harus memiliki hak istimewa `write:sessions`.",
        "operationId": "patch_v3_session_bulk_update_aml_hit_status",
        "x-didit-sdk": {
          "resource": "sessions",
          "method": "bulk_update_aml_hit_status",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Sessions"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "in": "path",
            "name": "sessionId",
            "required": true,
            "description": "UUID sesi verifikasi. Menerima ID sesi pengguna (KYC) dan bisnis (KYB) — layanan mencari ID tersebut di kedua jenis sesi.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "11111111-2222-3333-4444-555555555555"
            }
          },
          {
            "in": "query",
            "name": "node_id",
            "required": false,
            "description": "ID node graf alur kerja. Hanya diperlukan jika sesi memiliki beberapa pemeriksaan AML (satu per node); abaikan untuk sesi dengan AML tunggal.",
            "schema": {
              "type": "string",
              "example": "feature_aml_1"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "hit_updates"
                ],
                "properties": {
                  "hit_updates": {
                    "type": "array",
                    "description": "Daftar pembaruan hit yang tidak kosong.",
                    "items": {
                      "type": "object",
                      "required": [
                        "hit_id",
                        "review_status"
                      ],
                      "properties": {
                        "hit_id": {
                          "type": "string",
                          "example": "hit_7c1e9a40b2d35f86e0a4c912",
                          "description": "`id` dari hit dalam array `hits` pemeriksaan AML (`hit_...`). ID hit yang dikembalikan dalam format sebelumnya masih diterima."
                        },
                        "review_status": {
                          "type": "string",
                          "enum": [
                            "Unreviewed",
                            "Confirmed Match",
                            "False Positive",
                            "Inconclusive"
                          ],
                          "example": "Confirmed Match"
                        }
                      }
                    }
                  },
                  "node_id": {
                    "type": "string",
                    "description": "ID node graf opsional. Gunakan ID ini (di sini atau sebagai parameter kueri) saat sesi memiliki beberapa pemeriksaan AML.",
                    "example": "feature_aml_1"
                  }
                }
              },
              "example": {
                "hit_updates": [
                  {
                    "hit_id": "hit_7c1e9a40b2d35f86e0a4c912",
                    "review_status": "Confirmed Match"
                  },
                  {
                    "hit_id": "hit_3b8f20d6a91c4e75f0b2d6a8",
                    "review_status": "False Positive"
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Semua hit diperbarui.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "message",
                    "updated_hits"
                  ],
                  "properties": {
                    "message": {
                      "type": "string",
                      "description": "`Updated {n} hit(s) successfully`, dengan `n` adalah jumlah entri di `hit_updates`."
                    },
                    "updated_hits": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "`id` dari hit yang disebutkan oleh setiap entri di `hit_updates`, sebagaimana dikembalikan oleh keputusan sesi, sesuai urutan permintaan, termasuk hit yang statusnya tidak berubah."
                    }
                  }
                },
                "example": {
                  "message": "Updated 2 hit(s) successfully",
                  "updated_hits": [
                    "hit_7c1e9a40b2d35f86e0a4c912",
                    "hit_3b8f20d6a91c4e75f0b2d6a8"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Kesalahan validasi — `hit_updates` kosong, atau ada entri yang kehilangan `hit_id` / `review_status` atau memuat nilai yang tidak valid.",
            "content": {
              "application/json": {
                "example": {
                  "hit_updates": [
                    "hit_updates cannot be empty"
                  ]
                }
              }
            }
          },
          "403": {
            "description": "Kredensial tidak ada atau izin tidak mencukupi. Kunci yang tidak ada mengembalikan `403`; kunci yang salah, dicabut, atau kedaluwarsa mengembalikan `401`.",
            "content": {
              "application/json": {
                "examples": {
                  "Invalid Credentials": {
                    "summary": "x-api-key tidak ada atau tidak valid",
                    "value": {
                      "detail": "Authentication credentials were not provided or are invalid."
                    }
                  },
                  "Missing Privilege": {
                    "summary": "Kunci API tidak memiliki write:sessions",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Sesi tidak ditemukan, sesi tidak memiliki pemeriksaan AML, atau satu atau beberapa `hit_id` tidak ada (tidak ada hasil yang diubah dalam kasus tersebut).",
            "content": {
              "application/json": {
                "example": {
                  "detail": "Hits not found: hit_9d2e7f41c0a8b3e65d1f0c47"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X PATCH \\\n  https://verification.didit.me/v3/session/11111111-2222-3333-4444-555555555555/bulk-update-aml-hit-status/ \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"hit_updates\": [\n      { \"hit_id\": \"abc123\", \"review_status\": \"Confirmed Match\" },\n      { \"hit_id\": \"def456\", \"review_status\": \"False Positive\" }\n    ]\n  }'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.bulk_update_aml_hit_status(\n    \"11111111-2222-3333-4444-555555555555\",\n    hit_updates=[{\n        \"hit_id\": \"hit_7c1e9a40b2d35f86e0a4c912\",\n        \"review_status\": \"Confirmed Match\",\n    }, {\n        \"hit_id\": \"hit_3b8f20d6a91c4e75f0b2d6a8\",\n        \"review_status\": \"False Positive\",\n    }],\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.bulkUpdateAmlHitStatus(\"11111111-2222-3333-4444-555555555555\", {\n  hit_updates: [{\n    hit_id: \"hit_7c1e9a40b2d35f86e0a4c912\",\n    review_status: \"Confirmed Match\",\n  }, {\n    hit_id: \"hit_3b8f20d6a91c4e75f0b2d6a8\",\n    review_status: \"False Positive\",\n  }],\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.BulkUpdateAMLHitStatus(ctx, \"11111111-2222-3333-4444-555555555555\", didit.SessionsBulkUpdateAMLHitStatusParams{\n\tHitUpdates: []didit.SessionsBulkUpdateAMLHitStatusParamsHitUpdates{{\n\t\tHitID:        \"hit_7c1e9a40b2d35f86e0a4c912\",\n\t\tReviewStatus: \"Confirmed Match\",\n\t}, {\n\t\tHitID:        \"hit_3b8f20d6a91c4e75f0b2d6a8\",\n\t\tReviewStatus: \"False Positive\",\n\t}},\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.List;\nimport me.didit.Didit;\nimport me.didit.types.SessionsBulkUpdateAmlHitStatusParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().bulkUpdateAmlHitStatus(\"11111111-2222-3333-4444-555555555555\", SessionsBulkUpdateAmlHitStatusParams.builder()\n        .hitUpdates(List.of(\n                SessionsBulkUpdateAmlHitStatusParams.HitUpdates.builder()\n                        .hitId(\"hit_7c1e9a40b2d35f86e0a4c912\")\n                        .reviewStatus(SessionsBulkUpdateAmlHitStatusParams.HitUpdates.ReviewStatus.of(\"Confirmed Match\"))\n                        .build(),\n                SessionsBulkUpdateAmlHitStatusParams.HitUpdates.builder()\n                        .hitId(\"hit_3b8f20d6a91c4e75f0b2d6a8\")\n                        .reviewStatus(SessionsBulkUpdateAmlHitStatusParams.HitUpdates.ReviewStatus.of(\"False Positive\"))\n                        .build()))\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->sessions->bulkUpdateAmlHitStatus('11111111-2222-3333-4444-555555555555', [\n    'hit_updates' => [[\n        'hit_id' => 'hit_7c1e9a40b2d35f86e0a4c912',\n        'review_status' => 'Confirmed Match',\n    ], [\n        'hit_id' => 'hit_3b8f20d6a91c4e75f0b2d6a8',\n        'review_status' => 'False Positive',\n    ]],\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.bulk_update_aml_hit_status(\n  \"11111111-2222-3333-4444-555555555555\",\n  hit_updates: [{\n    hit_id: \"hit_7c1e9a40b2d35f86e0a4c912\",\n    review_status: \"Confirmed Match\",\n  }, {\n    hit_id: \"hit_3b8f20d6a91c4e75f0b2d6a8\",\n    review_status: \"False Positive\",\n  }]\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.BulkUpdateAmlHitStatusAsync(\"11111111-2222-3333-4444-555555555555\", new SessionsBulkUpdateAmlHitStatusParams\n{\n    HitUpdates = new SessionsBulkUpdateAmlHitStatusParamsHitUpdates[]\n    {\n        new()\n        {\n            HitId = \"hit_7c1e9a40b2d35f86e0a4c912\",\n            ReviewStatus = \"Confirmed Match\",\n        },\n        new()\n        {\n            HitId = \"hit_3b8f20d6a91c4e75f0b2d6a8\",\n            ReviewStatus = \"False Positive\",\n        },\n    },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/session/{sessionId}/update-poa-data/": {
      "patch": {
        "summary": "Perbarui data Bukti Alamat yang diekstrak dari dokumen POA pada sesi verifikasi",
        "description": "Koreksi kolom yang diekstraksi dari dokumen Bukti Alamat pengguna — tagihan utilitas, rekening koran, atau bukti alamat lainnya — setelah verifikasi selesai: penerbit, tanggal, nama yang tercetak, alamat itu sendiri, dan detail perbankan. Setiap kolom dalam body bersifat opsional: hanya kunci yang Anda kirim yang akan ditulis, sisanya dibiarkan tanpa perubahan (semantik `PATCH`).\n\nSesi harus menjadi milik aplikasi Anda dan berada dalam status `Approved`, `Declined`, `In Review`, atau `Kyc Expired`. Sesi dalam status lainnya (misalnya masih `In Progress`) mengembalikan `404` dengan `\"No Session matches the given query.\"` — berbeda dari `\"Not found.\"` yang dikembalikan untuk `sessionId` yang tidak dikenal atau telah dihapus. Sesi juga harus memiliki catatan POA: sesi yang alur kerjanya tidak pernah menjalankan langkah Bukti Alamat mengembalikan `404` (`\"The session does not have a POA.\"`). Untuk alur kerja graf dengan beberapa langkah POA, targetkan langkah tertentu dengan `node_id` (parameter kueri atau kolom body); jika dihilangkan, catatan POA terbaru yang akan di-patch.\n\n`extra_fields` digabungkan kunci demi kunci: sembilan kunci yang dikenal (`bank_iban`, `additional_names`, …) ditulis ke kolom POA khusus, kunci lainnya disimpan sebagai ekstra kustom, dan `null` / `\"\"` menghapus kunci. `poa_parsed_address` hanya menerima tujuh kunci yang terdokumentasi dan menghitung ulang `formatted_address` / `poa_formatted_address` setelah setiap pengeditan. Jika teks bebas `poa_address` berubah, server juga dapat melakukan geocoding ulang dan memperbarui alamat terstruktur (dilewati untuk sesi sandbox).\n\nBerbeda dengan varian KYC dari endpoint ini, [webhook](/id/integration/webhooks) `data.updated` (pemicu `manual_review`) hanya terpicu ketika setidaknya satu nilai yang disimpan **benar-benar berubah** — mengirim ulang nilai yang identik adalah no-op senyap. Saat nilai berubah, entri aktivitas `POA_DATA_UPDATED` yang mencatat kolom yang diubah beserta nilai sebelumnya dan nilai baru akan ditambahkan ke `reviews` sesi, yang terlihat di [Get Decision](#get-/v3/session/-sessionId-/decision/) dan linimasa aktivitas konsol. Status dan keputusan sesi **tidak** dievaluasi ulang — gunakan [Update Status](#patch-/v3/session/-sessionId-/update-status/) untuk mengubah hasilnya.\n\nMenerima kunci API atau token pengguna konsol; bagaimanapun kredensial memerlukan izin `write:sessions`. Kegagalan autentikasi dan izin keduanya mengembalikan `403` — API ini tidak pernah merespons `401`. Perhatikan bahwa pencarian sesi berjalan sebelum pemeriksaan kredensial, sehingga `sessionId` yang tidak dikenal mengembalikan `404` bahkan dengan kredensial yang tidak ada. Endpoint ini memiliki batas laju khusus sebesar 10 permintaan per menit per kunci API (permintaan tidak valid juga dihitung); kuota tulis bersama sebesar 300 permintaan per menit juga berlaku.\n\nBody JSON kosong `{}` adalah no-op: mengembalikan `200` yang menggemakan catatan POA saat ini tanpa memicu webhook (`has_changes` tetap false).",
        "operationId": "patch_v3_session_update_poa_data",
        "x-didit-sdk": {
          "resource": "sessions",
          "method": "update_poa_data",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Sessions"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "sessionId",
            "in": "path",
            "required": true,
            "description": "UUID sesi Verifikasi Pengguna (KYC) tempat Anda memperbaiki rekaman POA yang terlampir.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "11111111-2222-3333-4444-555555555555"
            }
          },
          {
            "name": "node_id",
            "in": "query",
            "required": false,
            "description": "Node graf alur kerja yang catatan POA-nya akan di-patch, untuk alur kerja graf dengan beberapa langkah Bukti Alamat (juga diterima sebagai kolom badan `node_id`). Jika diabaikan, catatan POA terbaru pada sesi tersebut yang akan di-patch. Jika tidak ada POA untuk node yang ditentukan, panggilan akan mengembalikan `404` (`\"The session does not have a POA for node '<node_id>'.\"`).",
            "schema": {
              "type": "string",
              "example": "feature_poa"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "description": "Semua kolom bersifat opsional — kirim hanya yang ingin Anda ubah.",
                "properties": {
                  "issuing_state": {
                    "type": "string",
                    "nullable": true,
                    "description": "Negara yang menerbitkan dokumen POA, ISO 3166-1 alpha-3. Tidak peka huruf besar/kecil (dinormalisasi ke huruf besar); kode yang tidak valid mengembalikan `400`.",
                    "example": "ESP"
                  },
                  "document_type": {
                    "type": "string",
                    "enum": [
                      "UTILITY_BILL",
                      "BANK_STATEMENT",
                      "GOVERNMENT_ISSUED_DOCUMENT",
                      "OTHER_POA_DOCUMENT",
                      "UNKNOWN"
                    ],
                    "description": "Kategori dokumen POA. Nilai berhuruf besar — varian huruf kecil seperti `utility_bill` mengembalikan `400`.",
                    "example": "UTILITY_BILL"
                  },
                  "document_language": {
                    "type": "string",
                    "maxLength": 50,
                    "nullable": true,
                    "description": "Bahasa dokumen, biasanya kode ISO 639-1 (misalnya `es`). Teks bebas — tidak divalidasi sebagai kode bahasa.",
                    "example": "es"
                  },
                  "issuer": {
                    "type": "string",
                    "maxLength": 255,
                    "nullable": true,
                    "description": "Organisasi yang menerbitkan dokumen (perusahaan utilitas, bank, lembaga pemerintah).",
                    "example": "Energy Provider S.A."
                  },
                  "issue_date": {
                    "type": "string",
                    "format": "date",
                    "nullable": true,
                    "description": "Tanggal penerbitan dokumen POA dalam format `YYYY-MM-DD`. Format lainnya mengembalikan `400`.",
                    "example": "2026-04-12"
                  },
                  "poa_address": {
                    "type": "string",
                    "nullable": true,
                    "description": "Alamat teks bebas seperti yang tertera pada dokumen. Ketika nilai ini berubah (hanya sesi non-sandbox) dan alamat terstruktur masih belum ada atau belum lengkap, server melakukan geocoding ulang di latar belakang pada permintaan yang sama dan dapat menimpa `poa_parsed_address` / `poa_formatted_address` dengan hasil geocoder. Geocoding ulang ini juga memerlukan adanya `issuing_state` pada catatan POA.",
                    "example": "Avda de Madrid 34, 28013 Madrid"
                  },
                  "name_on_document": {
                    "type": "string",
                    "maxLength": 255,
                    "nullable": true,
                    "description": "Nama penerima seperti yang tercetak pada dokumen.",
                    "example": "Carmen Espanola"
                  },
                  "extra_fields": {
                    "type": "object",
                    "additionalProperties": true,
                    "nullable": true,
                    "description": "Tambahan khusus dokumen, digabungkan kunci per kunci. Sembilan kunci dipetakan ke kolom Bukti Alamat khusus: `bank_account_number`, `bank_iban`, `bank_sort_code`, `bank_routing_number`, `bank_swift_bic`, `bank_branch_name`, `bank_branch_address`, `document_phone_number`, dan `additional_names` (harus berupa daftar string atau `null`, jika tidak `400`). Kunci lainnya disimpan sebagai kolom tambahan kustom. Semantik per kunci: suatu nilai menetapkan kunci; `null` atau `\"\"` menghapusnya. Harus berupa objek JSON, jika tidak `400`."
                  },
                  "poa_parsed_address": {
                    "type": "object",
                    "nullable": true,
                    "description": "Alamat terstruktur. Hanya kunci bersarang berikut yang diterima: `address_type`, `city`, `region`, `street_1`, `street_2`, `postal_code`, `country` — kunci lainnya akan mengembalikan `400`. Semantik per kunci: sebuah nilai menetapkan kunci, `null` menghapusnya. `formatted_address` (dan `poa_formatted_address` tingkat teratas) dihitung ulang di sisi server dengan menggabungkan `street_1`, `street_2`, `city`, `region`, `postal_code`, dan `country` — Anda tidak dapat menetapkannya secara langsung.",
                    "properties": {
                      "address_type": {
                        "type": "string",
                        "nullable": true,
                        "description": "Klasifikasi alamat bentuk bebas (misalnya `home`)."
                      },
                      "city": {
                        "type": "string",
                        "nullable": true,
                        "example": "Madrid"
                      },
                      "region": {
                        "type": "string",
                        "nullable": true,
                        "description": "Negara bagian / provinsi / komunitas otonom."
                      },
                      "street_1": {
                        "type": "string",
                        "nullable": true,
                        "example": "Avda de Madrid 34"
                      },
                      "street_2": {
                        "type": "string",
                        "nullable": true
                      },
                      "postal_code": {
                        "type": "string",
                        "nullable": true,
                        "example": "28013"
                      },
                      "country": {
                        "type": "string",
                        "nullable": true,
                        "description": "Kode negara ISO 3166-1 alpha-2. Input huruf kecil dinormalisasi ke huruf besar; kode alpha-3 ditolak dengan `400`.",
                        "example": "ES"
                      }
                    }
                  }
                }
              },
              "examples": {
                "Correct issuer and address": {
                  "summary": "Perbaiki klasifikasi dokumen, penerbit, dan alamat terstruktur",
                  "value": {
                    "issuing_state": "ESP",
                    "document_type": "BANK_STATEMENT",
                    "issuer": "Banco Example S.A.",
                    "issue_date": "2026-05-02",
                    "name_on_document": "Carmen Espanola",
                    "poa_address": "Avda de Madrid 34, 28013 Madrid",
                    "extra_fields": {
                      "bank_iban": "ES9121000418450200051332",
                      "additional_names": [
                        "Carmen E. Espanola"
                      ]
                    },
                    "poa_parsed_address": {
                      "street_1": "Avda de Madrid 34",
                      "city": "Madrid",
                      "postal_code": "28013",
                      "country": "ES"
                    }
                  }
                },
                "Remove a banking detail": {
                  "summary": "Hapus satu kunci kolom tambahan, simpan sisanya",
                  "value": {
                    "extra_fields": {
                      "bank_iban": null
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Data POA diperbarui. Mengembalikan **rekaman POA saat ini yang lengkap** (setiap kolom yang dapat diperbarui beserta nilai yang tersimpan, ditambah peta `extra_fields` lengkap, `poa_parsed_address`, dan `poa_formatted_address`) — bukan hanya kolom yang Anda kirimkan. Webhook `data.updated` hanya terpicu jika setidaknya ada satu nilai yang benar-benar berubah.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "issuing_state": {
                      "type": "string",
                      "nullable": true,
                      "description": "Negara yang menerbitkan dokumen POA, ISO 3166-1 alpha-3. Tidak peka huruf besar/kecil (dinormalisasi ke huruf besar); kode yang tidak valid mengembalikan `400`.",
                      "example": "ESP"
                    },
                    "document_type": {
                      "type": "string",
                      "enum": [
                        "UTILITY_BILL",
                        "BANK_STATEMENT",
                        "GOVERNMENT_ISSUED_DOCUMENT",
                        "OTHER_POA_DOCUMENT",
                        "UNKNOWN"
                      ],
                      "description": "Kategori dokumen POA. Nilai berhuruf besar — varian huruf kecil seperti `utility_bill` mengembalikan `400`.",
                      "example": "UTILITY_BILL"
                    },
                    "document_language": {
                      "type": "string",
                      "maxLength": 50,
                      "nullable": true,
                      "description": "Bahasa dokumen, biasanya kode ISO 639-1 (misalnya `es`). Teks bebas — tidak divalidasi sebagai kode bahasa.",
                      "example": "es"
                    },
                    "issuer": {
                      "type": "string",
                      "maxLength": 255,
                      "nullable": true,
                      "description": "Organisasi yang menerbitkan dokumen (perusahaan utilitas, bank, lembaga pemerintah).",
                      "example": "Energy Provider S.A."
                    },
                    "issue_date": {
                      "type": "string",
                      "format": "date",
                      "nullable": true,
                      "description": "Tanggal penerbitan dokumen POA dalam format `YYYY-MM-DD`. Format lainnya mengembalikan `400`.",
                      "example": "2026-04-12"
                    },
                    "poa_address": {
                      "type": "string",
                      "nullable": true,
                      "description": "Alamat teks bebas seperti yang tertera pada dokumen. Ketika nilai ini berubah (hanya sesi non-sandbox) dan alamat terstruktur masih belum ada atau belum lengkap, server melakukan geocoding ulang di latar belakang pada permintaan yang sama dan dapat menimpa `poa_parsed_address` / `poa_formatted_address` dengan hasil geocoder.",
                      "example": "Avda de Madrid 34, 28013 Madrid"
                    },
                    "name_on_document": {
                      "type": "string",
                      "maxLength": 255,
                      "nullable": true,
                      "description": "Nama penerima seperti yang tercetak pada dokumen.",
                      "example": "Carmen Espanola"
                    },
                    "extra_fields": {
                      "type": "object",
                      "additionalProperties": true,
                      "nullable": true,
                      "description": "Selalu ada dalam respons: sembilan kunci yang dikenal (dengan `null` untuk yang belum diatur, `additional_names` default ke `[]`) ditambah kunci kustom apa pun yang disimpan sebelumnya."
                    },
                    "poa_parsed_address": {
                      "type": "object",
                      "nullable": true,
                      "description": "Alamat terstruktur saat ini, atau `null` jika tidak ada. Mencakup `formatted_address` yang dihitung ulang bersama tujuh kunci yang dapat diedit. Dikembalikan seperti yang disimpan — setelah geocoding sisi server, ini dapat berisi kunci pembukuan (misalnya `raw_results`) bersama kunci yang dapat diedit.",
                      "properties": {
                        "address_type": {
                          "type": "string",
                          "nullable": true,
                          "description": "Klasifikasi alamat bentuk bebas (misalnya `home`)."
                        },
                        "city": {
                          "type": "string",
                          "nullable": true,
                          "example": "Madrid"
                        },
                        "region": {
                          "type": "string",
                          "nullable": true,
                          "description": "Negara bagian / provinsi / komunitas otonom."
                        },
                        "street_1": {
                          "type": "string",
                          "nullable": true,
                          "example": "Avda de Madrid 34"
                        },
                        "street_2": {
                          "type": "string",
                          "nullable": true
                        },
                        "postal_code": {
                          "type": "string",
                          "nullable": true,
                          "example": "28013"
                        },
                        "country": {
                          "type": "string",
                          "nullable": true,
                          "description": "Kode negara ISO 3166-1 alpha-2. Input huruf kecil dinormalisasi ke huruf besar; kode alpha-3 ditolak dengan `400`.",
                          "example": "ES"
                        },
                        "formatted_address": {
                          "type": "string",
                          "nullable": true,
                          "description": "Bentuk gabungan yang dapat dibaca manusia dari alamat terstruktur. Dihitung ulang di sisi server setelah setiap pengeditan `poa_parsed_address`.",
                          "example": "Avda de Madrid 34, Madrid, 28013, ES"
                        }
                      }
                    },
                    "poa_formatted_address": {
                      "type": "string",
                      "nullable": true,
                      "description": "Salinan tingkat atas dari `formatted_address` yang dihitung ulang, selalu disinkronkan saat alamat terstruktur berubah.",
                      "example": "Avda de Madrid 34, Madrid, 28013, ES"
                    }
                  }
                },
                "examples": {
                  "Updated POA": {
                    "summary": "Catatan POA lengkap setelah koreksi",
                    "value": {
                      "issuing_state": "ESP",
                      "document_type": "BANK_STATEMENT",
                      "document_language": "es",
                      "issuer": "Banco Example S.A.",
                      "issue_date": "2026-05-02",
                      "poa_address": "Avda de Madrid 34, 28013 Madrid",
                      "name_on_document": "Carmen Espanola",
                      "extra_fields": {
                        "bank_account_number": null,
                        "bank_iban": "ES9121000418450200051332",
                        "bank_sort_code": null,
                        "bank_routing_number": null,
                        "bank_swift_bic": null,
                        "bank_branch_name": null,
                        "bank_branch_address": null,
                        "document_phone_number": null,
                        "additional_names": [
                          "Carmen E. Espanola"
                        ]
                      },
                      "poa_parsed_address": {
                        "city": "Madrid",
                        "street_1": "Avda de Madrid 34",
                        "postal_code": "28013",
                        "country": "ES",
                        "formatted_address": "Avda de Madrid 34, Madrid, 28013, ES"
                      },
                      "poa_formatted_address": "Avda de Madrid 34, Madrid, 28013, ES"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Kesalahan validasi. Kesalahan kolom diterima sebagai `{\"<field>\": [\"<message>\"]}`; kesalahan pada kunci bertingkat `poa_parsed_address` / `extra_fields` menggunakan nilai objek: `{\"extra_fields\": {\"<key>\": \"<message>\"}}`.",
            "content": {
              "application/json": {
                "examples": {
                  "Invalid document type": {
                    "summary": "Enum menggunakan huruf besar — varian huruf kecil akan ditolak",
                    "value": {
                      "document_type": [
                        "\"utility_bill\" is not a valid choice."
                      ]
                    }
                  },
                  "Invalid issuing state": {
                    "summary": "issuing_state bukan ISO 3166-1 alpha-3",
                    "value": {
                      "issuing_state": [
                        "Invalid ISO 3166-1 alpha-3 country code for issuing_state."
                      ]
                    }
                  },
                  "additional_names not a list": {
                    "summary": "additional_names menerima daftar string atau null",
                    "value": {
                      "extra_fields": {
                        "additional_names": "Must be a list or null."
                      }
                    }
                  },
                  "Unsupported poa_parsed_address key": {
                    "summary": "Hanya tujuh kunci yang terdokumentasi yang diizinkan",
                    "value": {
                      "poa_parsed_address": {
                        "zipcode": "Unsupported key. Allowed keys: address_type, city, region, street_1, street_2, postal_code, country"
                      }
                    }
                  },
                  "Bad date format": {
                    "summary": "Tanggal harus berformat YYYY-MM-DD",
                    "value": {
                      "issue_date": [
                        "Date has wrong format. Use one of these formats instead: YYYY-MM-DD."
                      ]
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Kredensial tidak ada atau izin tidak mencukupi. Kunci yang tidak ada mengembalikan `403`; kunci yang salah, dicabut, atau kedaluwarsa mengembalikan `401`.",
            "content": {
              "application/json": {
                "examples": {
                  "Invalid Credentials": {
                    "summary": "x-api-key tidak ada atau tidak valid",
                    "value": {
                      "detail": "Authentication credentials were not provided or are invalid."
                    }
                  },
                  "Missing Privilege": {
                    "summary": "Kredensial tidak memiliki write:sessions",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Sesi tidak dikenal, sesi dalam status tidak dapat diedit, atau tidak ada rekaman POA untuk di-patch. Setiap kasus memiliki pesan `detail` yang berbeda (lihat contoh). Pencarian sesi yang tidak dikenal dijalankan sebelum pemeriksaan kredensial.",
            "content": {
              "application/json": {
                "examples": {
                  "Unknown session": {
                    "summary": "Tidak ada sesi dengan ID ini di aplikasi Anda (atau telah dihapus)",
                    "value": {
                      "detail": "Not found."
                    }
                  },
                  "Wrong session state": {
                    "summary": "Sesi ada tetapi tidak Approved / Declined / In Review / Kyc Expired",
                    "value": {
                      "detail": "No Session matches the given query."
                    }
                  },
                  "No POA record": {
                    "summary": "Alur kerja tidak pernah menjalankan langkah Bukti Alamat",
                    "value": {
                      "detail": "The session does not have a POA."
                    }
                  },
                  "No POA for node": {
                    "summary": "node_id diberikan tetapi tidak ada POA yang ada untuknya",
                    "value": {
                      "detail": "The session does not have a POA for node 'feature_missing'."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Batas laju khusus terlampaui — 10 pembaruan data POA per menit per kunci API (permintaan yang ditolak diperhitungkan ke dalam kuota). Kuota tulis bersama 300/menit juga dapat terpicu dengan pesannya sendiri. Periksa header respons `Retry-After` dan `X-RateLimit-*` sebelum mencoba lagi.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Rate limited": {
                    "summary": "Anggaran pembaruan POA habis",
                    "value": {
                      "detail": "Session POA data update rate limit exceeded. You can make up to 10 requests per minute."
                    }
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X PATCH \\\n  https://verification.didit.me/v3/session/11111111-2222-3333-4444-555555555555/update-poa-data/ \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"issuing_state\": \"ESP\",\n    \"document_type\": \"BANK_STATEMENT\",\n    \"issuer\": \"Banco Example S.A.\",\n    \"issue_date\": \"2026-05-02\",\n    \"name_on_document\": \"Carmen Espanola\",\n    \"poa_address\": \"Avda de Madrid 34, 28013 Madrid\",\n    \"extra_fields\": {\n      \"bank_iban\": \"ES9121000418450200051332\"\n    },\n    \"poa_parsed_address\": {\n      \"city\": \"Madrid\",\n      \"postal_code\": \"28013\",\n      \"country\": \"ES\"\n    }\n  }'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.update_poa_data(\n    \"11111111-2222-3333-4444-555555555555\",\n    issuing_state=\"ESP\",\n    document_type=\"BANK_STATEMENT\",\n    issuer=\"Banco Example S.A.\",\n    issue_date=\"2026-05-02\",\n    poa_address=\"Avda de Madrid 34, 28013 Madrid\",\n    name_on_document=\"Carmen Espanola\",\n    extra_fields={\"bank_iban\": \"ES9121000418450200051332\", \"additional_names\": [\"Carmen E. Espanola\"]},\n    poa_parsed_address={\n        \"city\": \"Madrid\",\n        \"street_1\": \"Avda de Madrid 34\",\n        \"postal_code\": \"28013\",\n        \"country\": \"ES\",\n    },\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.updatePoaData(\"11111111-2222-3333-4444-555555555555\", {\n  issuing_state: \"ESP\",\n  document_type: \"BANK_STATEMENT\",\n  issuer: \"Banco Example S.A.\",\n  issue_date: \"2026-05-02\",\n  poa_address: \"Avda de Madrid 34, 28013 Madrid\",\n  name_on_document: \"Carmen Espanola\",\n  extra_fields: { bank_iban: \"ES9121000418450200051332\", additional_names: [\"Carmen E. Espanola\"] },\n  poa_parsed_address: {\n    city: \"Madrid\",\n    street_1: \"Avda de Madrid 34\",\n    postal_code: \"28013\",\n    country: \"ES\",\n  },\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.UpdatePOAData(ctx, \"11111111-2222-3333-4444-555555555555\", didit.SessionsUpdatePOADataParams{\n\tIssuingState:   didit.String(\"ESP\"),\n\tDocumentType:   didit.Some(didit.SessionsUpdatePOADataParamsDocumentType(\"BANK_STATEMENT\")),\n\tIssuer:         didit.String(\"Banco Example S.A.\"),\n\tIssueDate:      didit.String(\"2026-05-02\"),\n\tPOAAddress:     didit.String(\"Avda de Madrid 34, 28013 Madrid\"),\n\tNameOnDocument: didit.String(\"Carmen Espanola\"),\n\tExtraFields:    didit.Some(map[string]any{\"bank_iban\": \"ES9121000418450200051332\", \"additional_names\": []any{\"Carmen E. Espanola\"}}),\n\tPOAParsedAddress: didit.Some(didit.SessionsUpdatePOADataParamsPOAParsedAddress{\n\t\tCity:       didit.String(\"Madrid\"),\n\t\tStreet1:    didit.String(\"Avda de Madrid 34\"),\n\t\tPostalCode: didit.String(\"28013\"),\n\t\tCountry:    didit.String(\"ES\"),\n\t}),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.time.LocalDate;\nimport java.util.List;\nimport java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.SessionsUpdatePoaDataParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().updatePoaData(\"11111111-2222-3333-4444-555555555555\", SessionsUpdatePoaDataParams.builder()\n        .issuingState(\"ESP\")\n        .documentType(SessionsUpdatePoaDataParams.DocumentType.of(\"BANK_STATEMENT\"))\n        .issuer(\"Banco Example S.A.\")\n        .issueDate(LocalDate.parse(\"2026-05-02\"))\n        .poaAddress(\"Avda de Madrid 34, 28013 Madrid\")\n        .nameOnDocument(\"Carmen Espanola\")\n        .extraFields(Map.of(\"bank_iban\", \"ES9121000418450200051332\", \"additional_names\", List.of(\"Carmen E. Espanola\")))\n        .poaParsedAddress(SessionsUpdatePoaDataParams.PoaParsedAddress.builder()\n                .city(\"Madrid\")\n                .street1(\"Avda de Madrid 34\")\n                .postalCode(\"28013\")\n                .country(\"ES\")\n                .build())\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->sessions->updatePoaData('11111111-2222-3333-4444-555555555555', [\n    'issuing_state' => 'ESP',\n    'document_type' => 'BANK_STATEMENT',\n    'issuer' => 'Banco Example S.A.',\n    'issue_date' => '2026-05-02',\n    'poa_address' => 'Avda de Madrid 34, 28013 Madrid',\n    'name_on_document' => 'Carmen Espanola',\n    'extra_fields' => ['bank_iban' => 'ES9121000418450200051332', 'additional_names' => ['Carmen E. Espanola']],\n    'poa_parsed_address' => [\n        'city' => 'Madrid',\n        'street_1' => 'Avda de Madrid 34',\n        'postal_code' => '28013',\n        'country' => 'ES',\n    ],\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.update_poa_data(\n  \"11111111-2222-3333-4444-555555555555\",\n  issuing_state: \"ESP\",\n  document_type: \"BANK_STATEMENT\",\n  issuer: \"Banco Example S.A.\",\n  issue_date: \"2026-05-02\",\n  poa_address: \"Avda de Madrid 34, 28013 Madrid\",\n  name_on_document: \"Carmen Espanola\",\n  extra_fields: { bank_iban: \"ES9121000418450200051332\", additional_names: [\"Carmen E. Espanola\"] },\n  poa_parsed_address: {\n    city: \"Madrid\",\n    street_1: \"Avda de Madrid 34\",\n    postal_code: \"28013\",\n    country: \"ES\",\n  }\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.UpdatePoaDataAsync(\"11111111-2222-3333-4444-555555555555\", new SessionsUpdatePoaDataParams\n{\n    IssuingState = \"ESP\",\n    DocumentType = new SessionsUpdatePoaDataParamsDocumentType(\"BANK_STATEMENT\"),\n    Issuer = \"Banco Example S.A.\",\n    IssueDate = \"2026-05-02\",\n    PoaAddress = \"Avda de Madrid 34, 28013 Madrid\",\n    NameOnDocument = \"Carmen Espanola\",\n    ExtraFields = new Dictionary<string, object> { [\"bank_iban\"] = \"ES9121000418450200051332\", [\"additional_names\"] = new object[] { \"Carmen E. Espanola\" } },\n    PoaParsedAddress = new SessionsUpdatePoaDataParamsPoaParsedAddress\n    {\n        City = \"Madrid\",\n        Street1 = \"Avda de Madrid 34\",\n        PostalCode = \"28013\",\n        Country = \"ES\",\n    },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/session/{sessionId}/kyb/{companyUuid}/update-data/": {
      "patch": {
        "summary": "Perbarui data perusahaan hasil ekstraksi registri pada sesi Verifikasi Bisnis (KYB)",
        "description": "Koreksi data perusahaan yang diekstrak dari registri pada sesi Verifikasi Bisnis (KYB) — nama perusahaan, nomor registrasi, alamat, status, detail kontak — yang diidentifikasi oleh `companyUuid`. Pemanggil umum mencakup analis kepatuhan yang memperbaiki salah baca registri, atau back office Anda yang menyinkronkan data perusahaan yang telah dikoreksi. Setiap kolom di dalam body bersifat opsional (semantik `PATCH`); body JSON kosong (`{}`) adalah no-op yang hanya menggemakan rekaman perusahaan saat ini.\n\nPengeditan ditulis di dua tempat sekaligus: kolom dengan kolom perusahaan kanonis (nama, nomor registrasi, negara, tanggal pendirian, nomor pajak, jenis, status, kolom modal (`registered_capital`, `registered_capital_amount`, `registered_capital_currency`), nama alternatif, bidang usaha, situs web, email, telepon, LEI, lokasi, dan `legal_address` → `registered_address`) memperbarui kolom tersebut, dan **setiap** kunci yang dikirimkan juga digabungkan ke dalam snapshot `registry_data` (tanggal sebagai string ISO) sehingga tampilan \"diekstrak dari registri\" mencerminkan koreksi tersebut. Kolom tanpa kolom kanonis — `region`, `registration_date`, `dissolution_date`, `control_scheme` — hanya masuk ke `registry_data`. `user_provided_data` (apa yang dikonfirmasi oleh pengguna akhir dalam alur yang di-hosting) tidak pernah disentuh, dan `last_console_edit_at` dicantumkan pada setiap PATCH yang tidak kosong.\n\nTidak seperti endpoint pembaruan KYC/POA, **tidak ada pembatasan status sesi**: perusahaan dapat diedit kapan saja dalam siklus hidup sesi bisnis. Perusahaan harus termasuk dalam sesi di path (`404` dengan `\"KYB company does not belong to the given session.\"` jika tidak) dan milik aplikasi Anda. Setiap PATCH yang tidak kosong memicu [webhook](/id/integration/webhooks) `data.updated` pada sesi bisnis (pemicu `console_registry_edit`) — bahkan ketika nilai yang dikirimkan sama dengan nilai yang disimpan. Status dan keputusan sesi **tidak** dievaluasi ulang, dan tidak ada entri peninjauan/audit yang dicatat.\n\nMenerima kunci API atau token pengguna konsol; bagaimanapun kredensial memerlukan izin `write:businesses`. Kegagalan autentikasi dan izin keduanya mengembalikan `403` — API ini tidak pernah merespons `401`. Perhatikan bahwa pencarian sesi berjalan sebelum pemeriksaan kredensial, sehingga `sessionId` yang tidak dikenal mengembalikan `404` bahkan dengan kredensial yang hilang. Anggaran penulisan bersama sebesar 300 permintaan per menit per kunci API berlaku.\n\nUntuk sesi Verifikasi Pengguna, padanan KYC-nya adalah `PATCH /v3/session/{sessionId}/update-data/`; untuk mengubah keputusan sesi itu sendiri, gunakan `PATCH /v3/session/{sessionId}/update-status/`.",
        "operationId": "patch_v3_session_kyb_company_update_data",
        "x-didit-sdk": {
          "resource": "sessions",
          "method": "update_kyb_company_data",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Sessions"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "sessionId",
            "in": "path",
            "required": true,
            "description": "UUID dari sesi induk Verifikasi Bisnis (KYB).",
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "33333333-4444-5555-6666-777777777777"
            }
          },
          {
            "name": "companyUuid",
            "in": "path",
            "required": true,
            "description": "UUID rekaman perusahaan yang akan diperbarui (`registry_checks[].company.uuid` pada keputusan sesi bisnis). Harus dimiliki oleh sesi yang dirujuk oleh `sessionId`.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "88888888-9999-aaaa-bbbb-cccccccccccc"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "description": "Semua kolom bersifat opsional — kirimkan hanya apa yang ingin Anda ubah. Kolom yang diberikan akan memperbarui kolom kanonis perusahaan (jika ada) dan digabungkan ke dalam snapshot `registry_data`.",
                "properties": {
                  "company_name": {
                    "type": "string",
                    "maxLength": 255,
                    "description": "Nama resmi perusahaan. Ditulis ke kolom kanonikal dan snapshot registri.",
                    "example": "Docs Probe Corp"
                  },
                  "registration_number": {
                    "type": "string",
                    "maxLength": 100,
                    "description": "Nomor registrasi resmi pada registri perusahaan.",
                    "example": "DPC-001"
                  },
                  "country_code": {
                    "type": "string",
                    "maxLength": 2,
                    "description": "Negara pendirian, ISO 3166-1 alpha-2. Tidak peka huruf besar/kecil (`us` disimpan sebagai `US`). Kode alpha-3 gagal memenuhi batas 2 karakter dengan `400`.",
                    "example": "US"
                  },
                  "region": {
                    "type": "string",
                    "maxLength": 10,
                    "nullable": true,
                    "description": "Tag subdivisi / wilayah jika registri memilikinya (misalnya negara bagian AS). Disimpan dalam cuplikan registri saja — tidak memiliki kolom kanonikal."
                  },
                  "incorporation_date": {
                    "type": "string",
                    "format": "date",
                    "description": "Tanggal pendirian dalam `YYYY-MM-DD`. Opsional, seperti semua kolom lainnya — `PATCH` bersifat parsial. Format tanggal lainnya mengembalikan `400`.",
                    "example": "2015-04-12"
                  },
                  "registration_date": {
                    "type": "string",
                    "format": "date",
                    "nullable": true,
                    "description": "Tanggal pendaftaran jika registri membedakannya dari pendirian. Hanya disimpan dalam snapshot registri."
                  },
                  "dissolution_date": {
                    "type": "string",
                    "format": "date",
                    "nullable": true,
                    "description": "Tanggal pembubaran untuk perusahaan yang sudah tidak aktif. Hanya disimpan dalam snapshot registri."
                  },
                  "tax_number": {
                    "type": "string",
                    "maxLength": 100,
                    "description": "ID pajak."
                  },
                  "legal_address": {
                    "type": "string",
                    "description": "Alamat hukum / terdaftar. Di-alias di sisi server menjadi kolom kanonik `registered_address` — respons mengembalikannya di bawah `registered_address`, sedangkan snapshot registri mempertahankan kunci `legal_address` yang Anda kirim.",
                    "example": "1 Example Plaza, Wilmington, DE 19801"
                  },
                  "company_type": {
                    "type": "string",
                    "maxLength": 100,
                    "description": "Jenis entitas hukum (misalnya `Limited Liability Company`, `PLC`, `GmbH`).",
                    "example": "Limited Liability Company"
                  },
                  "registry_status": {
                    "type": "string",
                    "enum": [
                      "active",
                      "dissolved",
                      "deregistered",
                      "see full details",
                      "authorised",
                      "appointed representative",
                      "unauthorised",
                      "inactive",
                      "no longer authorised",
                      "closed",
                      "struck off"
                    ],
                    "nullable": true,
                    "description": "Status perusahaan yang dilaporkan registri. Huruf kecil, beberapa nilai mengandung spasi (misalnya `struck off`, `no longer authorised`). Nilai lainnya mengembalikan `400`.",
                    "example": "active"
                  },
                  "verification_status": {
                    "type": "string",
                    "enum": [
                      "verified",
                      "failed",
                      "unknown"
                    ],
                    "nullable": true,
                    "description": "Hasil verifikasi registri. Nilai lainnya menghasilkan `400`.",
                    "example": "verified"
                  },
                  "alternative_names": {
                    "type": "string",
                    "description": "Nama dagang, nama resmi sebelumnya, nama DBA (teks bebas)."
                  },
                  "nature_of_business": {
                    "type": "string",
                    "description": "Deskripsi singkat mengenai aktivitas perusahaan.",
                    "example": "Software development"
                  },
                  "registered_capital": {
                    "type": "string",
                    "maxLength": 100,
                    "description": "Modal terdaftar yang dapat dibaca manusia (misalnya `USD 50000`). Gunakan `registered_capital_amount` + `registered_capital_currency` untuk nilai terstruktur, atau kolom ini untuk teks bentuk bebas.",
                    "example": "USD 50000"
                  },
                  "registered_capital_amount": {
                    "type": "number",
                    "format": "double",
                    "nullable": true,
                    "description": "Jumlah modal terdaftar numerik (hingga 20 digit, 2 tempat desimal). Menetapkan kolom `registered_capital_amount` dan dicerminkan ke dalam `registry_data` sebagai string desimal; respons menampilkannya kembali sebagai string desimal (misalnya `\"1500000.50\"`)."
                  },
                  "registered_capital_currency": {
                    "type": "string",
                    "maxLength": 3,
                    "nullable": true,
                    "description": "Kode mata uang ISO 4217 untuk `registered_capital_amount`. Tidak peka huruf besar/kecil (`usd` disimpan sebagai `USD`); nilai yang bukan tepat 3 huruf mengembalikan `400` dengan pesan ISO 4217. Menyetel kolom kanonikal `registered_capital_currency` dan disalin ke `registry_data`.",
                    "example": "USD"
                  },
                  "website": {
                    "type": "string",
                    "maxLength": 500,
                    "description": "Situs web perusahaan. Domain tanpa awalan protokol diterima dan dinormalisasi dengan awalan `https://` (`docsprobe.example.com` disimpan sebagai `https://docsprobe.example.com`); nilai yang tetap gagal dalam validasi URL mengembalikan `400`.",
                    "example": "https://docsprobe.example.com"
                  },
                  "email": {
                    "type": "string",
                    "format": "email",
                    "description": "Email kontak yang terdaftar di registri.",
                    "example": "legal@docsprobe.example.com"
                  },
                  "phone": {
                    "type": "string",
                    "maxLength": 50,
                    "description": "Telepon kontak. Harus hanya berisi `+`, digit, spasi, tanda hubung, titik, atau tanda kurung, dengan total 7-15 digit — jika tidak, akan menghasilkan `400`.",
                    "example": "+1 302 555 0143"
                  },
                  "legal_entity_identifier": {
                    "type": "string",
                    "maxLength": 50,
                    "description": "LEI, jika perusahaan memilikinya."
                  },
                  "location_of_registration": {
                    "type": "string",
                    "maxLength": 255,
                    "description": "Kota / subdivisi dari registri pencatatan."
                  },
                  "vat_number": {
                    "type": "string",
                    "maxLength": 64,
                    "description": "Nomor PPN Uni Eropa. Hanya digabungkan ke dalam snapshot `registry_data` — mengeditnya di sini tidak menjalankan ulang validasi PPN dan ID pajak, sehingga `vat_validation_status` dan kolom hasil `vat_*` lainnya tidak berubah."
                  },
                  "control_scheme": {
                    "type": "string",
                    "description": "Skema kontrol / tata kelola jika registri menyediakannya. Disimpan di snapshot registri saja."
                  }
                }
              },
              "examples": {
                "Correct registry data": {
                  "summary": "Perbaiki kolom yang diekstraksi dari registri perusahaan",
                  "value": {
                    "company_name": "Docs Probe Corp",
                    "registration_number": "DPC-001",
                    "country_code": "US",
                    "incorporation_date": "2015-04-12",
                    "company_type": "Limited Liability Company",
                    "legal_address": "1 Example Plaza, Wilmington, DE 19801",
                    "registry_status": "active",
                    "verification_status": "verified",
                    "website": "docsprobe.example.com",
                    "email": "legal@docsprobe.example.com",
                    "phone": "+1 302 555 0143",
                    "registered_capital": "USD 50000",
                    "nature_of_business": "Software development"
                  }
                },
                "Single field": {
                  "summary": "Hanya kunci yang Anda kirimkan yang ditulis",
                  "value": {
                    "registry_status": "dissolved"
                  }
                },
                "No-op": {
                  "summary": "Isi kosong mengembalikan rekaman saat ini tanpa memicu webhook",
                  "value": {}
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Data perusahaan diperbarui (atau dikembalikan tanpa perubahan untuk isi permintaan yang kosong). Mengembalikan catatan perusahaan KYB lengkap — bentuk yang sama seperti `registry_checks[].company` pada keputusan sesi bisnis. Perhatikan bagaimana `legal_address` dikembalikan sebagai `registered_address`. `registered_capital_amount`/`registered_capital_currency` mengisi kolom kanonisnya dan dicerminkan ke dalam `registry_data`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Catatan lengkap perusahaan KYB — bentuk yang sama dengan objek `company` di dalam `registry_checks[]` pada keputusan sesi bisnis.",
                  "properties": {
                    "uuid": {
                      "type": "string",
                      "format": "uuid",
                      "description": "Pengidentifikasi catatan perusahaan (parameter jalur `companyUuid`)."
                    },
                    "node_id": {
                      "type": "string",
                      "nullable": true,
                      "description": "Node graf alur kerja tempat catatan perusahaan ini berada, jika alur kerja berbasis graf."
                    },
                    "status": {
                      "type": "string",
                      "description": "Status siklus hidup fitur dari pemeriksaan registri (misalnya `Not Finished`, `Approved`, `Declined`, `In Review`)."
                    },
                    "registry_status": {
                      "type": "string",
                      "nullable": true,
                      "description": "Status perusahaan yang dilaporkan registri (misalnya `active`, `dissolved`, `struck off`)."
                    },
                    "data_resolved": {
                      "type": "boolean",
                      "description": "`true` saat data perusahaan lengkap — selalu `true` untuk perusahaan entri manual; untuk perusahaan yang bersumber dari registri, `true` setelah pengambilan data registri selesai."
                    },
                    "company_name": {
                      "type": "string",
                      "nullable": true
                    },
                    "registration_number": {
                      "type": "string",
                      "nullable": true
                    },
                    "country_code": {
                      "type": "string",
                      "nullable": true,
                      "description": "Kode ISO 3166-1 alpha-2 negara pendirian."
                    },
                    "region": {
                      "type": "string",
                      "nullable": true
                    },
                    "company_type": {
                      "type": "string",
                      "nullable": true
                    },
                    "incorporation_date": {
                      "type": "string",
                      "format": "date",
                      "nullable": true
                    },
                    "registered_address": {
                      "type": "string",
                      "nullable": true,
                      "description": "Alamat terdaftar kanonik — diperbarui saat Anda mengirim `legal_address`."
                    },
                    "tax_number": {
                      "type": "string",
                      "nullable": true
                    },
                    "risk_level": {
                      "type": "string",
                      "nullable": true
                    },
                    "verification_status": {
                      "type": "string",
                      "nullable": true,
                      "description": "`verified`, `failed`, atau `unknown`."
                    },
                    "is_from_registry": {
                      "type": "boolean",
                      "description": "`true` saat data perusahaan diisi otomatis dari pencarian registri alih-alih dimasukkan secara manual."
                    },
                    "fetch_status": {
                      "type": "string",
                      "nullable": true,
                      "description": "Siklus hidup pengambilan registri untuk perusahaan yang bersumber dari registri (`pending` / `resolved`); `null` untuk entri manual."
                    },
                    "alternative_names": {
                      "type": "string",
                      "nullable": true,
                      "description": "Nama perusahaan alternatif, nama dagang, nama terdahulu, atau nama dalam bahasa asli sebagai teks, jika dilaporkan."
                    },
                    "nature_of_business": {
                      "type": "string",
                      "nullable": true
                    },
                    "registered_capital": {
                      "type": "string",
                      "nullable": true
                    },
                    "registered_capital_amount": {
                      "type": "string",
                      "nullable": true,
                      "description": "Kolom kanonis. Dikembalikan sebagai string desimal (misalnya `\"2750000.00\"`)."
                    },
                    "registered_capital_currency": {
                      "type": "string",
                      "nullable": true,
                      "description": "Kolom kanonis. Disetel oleh alur registri atau melalui pengeditan konsol/API lewat endpoint ini."
                    },
                    "website": {
                      "type": "string",
                      "nullable": true
                    },
                    "email": {
                      "type": "string",
                      "nullable": true
                    },
                    "phone": {
                      "type": "string",
                      "nullable": true
                    },
                    "legal_entity_identifier": {
                      "type": "string",
                      "nullable": true
                    },
                    "location_of_registration": {
                      "type": "string",
                      "nullable": true
                    },
                    "vat_number": {
                      "type": "string",
                      "nullable": true,
                      "description": "Nomor PPN Uni Eropa, saat dikumpulkan selama langkah registri yang di-hosting atau diedit sesudahnya."
                    },
                    "vat_validation_status": {
                      "type": "string",
                      "enum": [
                        "valid",
                        "invalid",
                        "format_valid",
                        "invalid_format",
                        "could_not_validate",
                        "not_applicable"
                      ],
                      "description": "Hasil validasi nomor PPN atau, jika tidak ada, `tax_number`, saat pengiriman ke registri. `valid` / `invalid`: ditentukan oleh registri resmi negara (EU VIES, Norwegia, Swiss, Brasil, Kolombia, Kosta Rika, Ekuador, Paraguay; Polandia juga melalui registri PPN domestiknya). `format_valid` / `invalid_format`: ditentukan oleh aturan format dan digit centang negara tersebut jika tidak ada registri yang dapat dikueri. `could_not_validate`: registri tidak tersedia. `not_applicable`: tidak ada nomor, negara tanpa registri atau aturan, atau sesi sandbox."
                    },
                    "vat_validated_number": {
                      "type": "string",
                      "nullable": true,
                      "description": "Nomor yang diperiksa, sebagaimana diketahui oleh sumber (misalnya nomor PPN yang diperoleh dari SIREN Prancis atau RSIN Belanda). `null` jika tidak ada pemeriksaan yang dijalankan."
                    },
                    "vat_validation_source": {
                      "type": "string",
                      "nullable": true,
                      "enum": [
                        "eu_vies",
                        "pl_vat_white_list",
                        "no_brreg",
                        "ch_uid_register",
                        "br_receita_federal",
                        "co_rues",
                        "cr_hacienda",
                        "ec_sri",
                        "py_dnit",
                        "format_rules",
                        null
                      ],
                      "description": "Sumber yang menentukan `vat_validation_status`: registri resmi, atau `format_rules`. `null` jika tidak ada pemeriksaan yang dijalankan."
                    },
                    "vat_validated_name": {
                      "type": "string",
                      "nullable": true,
                      "description": "Nama yang terdaftar pada sumber yang memvalidasi nomor tersebut, jika menyediakannya. Hanya ditetapkan saat statusnya `valid`."
                    },
                    "vat_validated_address": {
                      "type": "string",
                      "nullable": true,
                      "description": "Alamat yang terdaftar pada sumber yang memvalidasi nomor tersebut, jika sumber mengungkapkannya. Hanya diisi jika statusnya `valid`."
                    },
                    "vat_checked_at": {
                      "type": "string",
                      "format": "date-time",
                      "nullable": true,
                      "description": "Cap waktu pemeriksaan. `null` jika tidak ada pemeriksaan yang dilakukan."
                    },
                    "financial_summary": {
                      "type": "object",
                      "nullable": true,
                      "additionalProperties": true
                    },
                    "officers": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "additionalProperties": true
                      },
                      "description": "Direktur / petugas yang terikat dengan perusahaan, termasuk progres KYC per orang."
                    },
                    "beneficial_owners": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "additionalProperties": true
                      },
                      "description": "Pemilik manfaat yang terkait dengan perusahaan, termasuk progres KYC per orang."
                    },
                    "addresses": {
                      "type": "array",
                      "nullable": true,
                      "items": {
                        "type": "object",
                        "additionalProperties": true
                      },
                      "description": "Detail alamat registri, jika registri mengembalikannya."
                    },
                    "industries": {
                      "type": "array",
                      "nullable": true,
                      "items": {
                        "type": "object",
                        "additionalProperties": true
                      },
                      "description": "Klasifikasi industri registri, jika tersedia."
                    },
                    "accounts": {
                      "type": "object",
                      "nullable": true,
                      "additionalProperties": true,
                      "description": "Tanggal pengajuan registri, jika tersedia. Laporan tahunan dan rapat umum menggunakan last_annual_return_date dan last_agm_date; keduanya berbeda dari laporan keuangan."
                    },
                    "registry_data": {
                      "$ref": "#/components/schemas/KYBRegistryData"
                    },
                    "user_provided_data": {
                      "type": "object",
                      "nullable": true,
                      "additionalProperties": true,
                      "description": "Apa yang diketik pengguna akhir selama langkah konfirmasi registri yang di-hosting. Tidak pernah dimodifikasi oleh endpoint ini."
                    },
                    "confirmed_by_user_at": {
                      "type": "string",
                      "format": "date-time",
                      "nullable": true,
                      "description": "Waktu ketika pengguna akhir mengonfirmasi data perusahaan dalam alur yang dihosting."
                    },
                    "last_console_edit_at": {
                      "type": "string",
                      "format": "date-time",
                      "nullable": true,
                      "description": "Diberi penanda pada setiap PATCH non-kosong yang berhasil, sehingga UI dapat menampilkan konteks \"diedit oleh operator\"."
                    },
                    "is_editable": {
                      "type": "boolean",
                      "description": "`true` selama pengguna akhir masih dapat mengedit data yang bersumber dari registri di alur yang di-hosting (bersumber dari registri dan belum dikonfirmasi)."
                    }
                  }
                },
                "examples": {
                  "Updated company": {
                    "summary": "Catatan lengkap perusahaan setelah koreksi",
                    "value": {
                      "uuid": "6b9479f5-6769-46c8-baf1-df63bbbc5f8c",
                      "node_id": null,
                      "status": "Not Finished",
                      "registry_status": "active",
                      "data_resolved": true,
                      "company_name": "Docs Probe Corp",
                      "registration_number": "DPC-001",
                      "country_code": "US",
                      "region": null,
                      "company_type": "Limited Liability Company",
                      "incorporation_date": "2015-04-12",
                      "registered_address": "1 Example Plaza, Wilmington, DE 19801",
                      "tax_number": null,
                      "risk_level": null,
                      "verification_status": "verified",
                      "is_from_registry": false,
                      "fetch_status": null,
                      "alternative_names": null,
                      "nature_of_business": "Software development",
                      "registered_capital": "USD 50000",
                      "registered_capital_amount": null,
                      "registered_capital_currency": "USD",
                      "website": "https://docsprobe.example.com",
                      "email": "legal@docsprobe.example.com",
                      "phone": "+1 302 555 0143",
                      "legal_entity_identifier": null,
                      "location_of_registration": null,
                      "financial_summary": null,
                      "officers": [],
                      "beneficial_owners": [],
                      "addresses": null,
                      "industries": null,
                      "accounts": null,
                      "registry_data": {
                        "company_name": "Docs Probe Corp",
                        "registration_number": "DPC-001",
                        "country_code": "US",
                        "incorporation_date": "2015-04-12",
                        "legal_address": "1 Example Plaza, Wilmington, DE 19801",
                        "company_type": "Limited Liability Company",
                        "registry_status": "active",
                        "verification_status": "verified",
                        "nature_of_business": "Software development",
                        "registered_capital": "USD 50000",
                        "registered_capital_currency": "USD",
                        "website": "https://docsprobe.example.com",
                        "email": "legal@docsprobe.example.com",
                        "phone": "+1 302 555 0143"
                      },
                      "user_provided_data": null,
                      "confirmed_by_user_at": null,
                      "last_console_edit_at": "2026-06-12T00:02:34.276061Z",
                      "is_editable": false
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Kesalahan validasi. Kesalahan kolom diterima sebagai `{\"<field>\": [\"<message>\"]}`. Pemeriksaan panjang maksimum dijalankan sebelum pemeriksaan format, sehingga `country_code: \"USA\"` melaporkan batas 2 karakter alih-alih pesan ISO.",
            "content": {
              "application/json": {
                "examples": {
                  "Alpha-3 country code": {
                    "summary": "country_code harus berupa alpha-2 — pemeriksaan panjang dijalankan terlebih dahulu",
                    "value": {
                      "country_code": [
                        "Ensure this field has no more than 2 characters."
                      ]
                    }
                  },
                  "Non-alphabetic country code": {
                    "summary": "2 karakter tetapi bukan huruf",
                    "value": {
                      "country_code": [
                        "country_code must be a 2-letter ISO 3166-1 alpha-2 code."
                      ]
                    }
                  },
                  "Invalid currency": {
                    "summary": "3 karakter tetapi bukan kode ISO 4217",
                    "value": {
                      "registered_capital_currency": [
                        "Currency must be a 3-letter ISO 4217 code (e.g. USD, EUR, GBP)."
                      ]
                    }
                  },
                  "Invalid phone": {
                    "summary": "Nomor telepon gagal dalam pemeriksaan format / jumlah digit",
                    "value": {
                      "phone": [
                        "Invalid phone number format."
                      ]
                    }
                  },
                  "Invalid registry status": {
                    "summary": "registry_status tidak ada dalam enum",
                    "value": {
                      "registry_status": [
                        "\"liquidated\" is not a valid choice."
                      ]
                    }
                  },
                  "Invalid email": {
                    "summary": "Alamat email salah format",
                    "value": {
                      "email": [
                        "Enter a valid email address."
                      ]
                    }
                  },
                  "Invalid website": {
                    "summary": "Nilai gagal validasi URL bahkan setelah normalisasi https://",
                    "value": {
                      "website": [
                        "Enter a valid URL."
                      ]
                    }
                  },
                  "Bad date format": {
                    "summary": "Tanggal harus berformat YYYY-MM-DD",
                    "value": {
                      "incorporation_date": [
                        "Date has wrong format. Use one of these formats instead: YYYY-MM-DD."
                      ]
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Kredensial tidak ada atau izin tidak mencukupi. Kunci yang tidak ada mengembalikan `403`; kunci yang salah, dicabut, atau kedaluwarsa mengembalikan `401`.",
            "content": {
              "application/json": {
                "examples": {
                  "Invalid Credentials": {
                    "summary": "x-api-key tidak ada atau tidak valid",
                    "value": {
                      "detail": "Authentication credentials were not provided or are invalid."
                    }
                  },
                  "Missing Privilege": {
                    "summary": "Kredensial tidak memiliki write:businesses",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Sesi tidak dikenal, perusahaan tidak dikenal, atau perusahaan yang terkait dengan sesi yang berbeda. Setiap kasus memiliki pesan `detail` yang berbeda (lihat contoh). Pencarian sesi yang tidak dikenal dijalankan sebelum pemeriksaan kredensial.",
            "content": {
              "application/json": {
                "examples": {
                  "Unknown session": {
                    "summary": "Tidak ada sesi dengan ID ini di aplikasi Anda (atau telah dihapus)",
                    "value": {
                      "detail": "Not found."
                    }
                  },
                  "Unknown company": {
                    "summary": "Tidak ada perusahaan dengan UUID ini di aplikasi Anda",
                    "value": {
                      "detail": "No KYBCompany matches the given query."
                    }
                  },
                  "Company / session mismatch": {
                    "summary": "companyUuid ada tetapi milik sesi lain",
                    "value": {
                      "detail": "KYB company does not belong to the given session."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Batas laju penulisan bersama terlampaui (300 permintaan POST/PATCH/DELETE per menit per kunci API). Periksa header respons `Retry-After` dan `X-RateLimit-*` sebelum mencoba lagi.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Rate limited": {
                    "summary": "Anggaran penulisan habis",
                    "value": {
                      "detail": "Write request rate limit exceeded. You can make up to 300 requests per minute."
                    }
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X PATCH \\\n  https://verification.didit.me/v3/session/33333333-4444-5555-6666-777777777777/kyb/88888888-9999-aaaa-bbbb-cccccccccccc/update-data/ \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"company_name\": \"Docs Probe Corp\",\n    \"registration_number\": \"DPC-001\",\n    \"country_code\": \"US\",\n    \"incorporation_date\": \"2015-04-12\",\n    \"company_type\": \"Limited Liability Company\",\n    \"legal_address\": \"1 Example Plaza, Wilmington, DE 19801\",\n    \"registry_status\": \"active\"\n  }'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.update_kyb_company_data(\n    \"33333333-4444-5555-6666-777777777777\",\n    \"88888888-9999-aaaa-bbbb-cccccccccccc\",\n    company_name=\"Docs Probe Corp\",\n    registration_number=\"DPC-001\",\n    country_code=\"US\",\n    incorporation_date=\"2015-04-12\",\n    legal_address=\"1 Example Plaza, Wilmington, DE 19801\",\n    company_type=\"Limited Liability Company\",\n    registry_status=\"active\",\n    verification_status=\"verified\",\n    nature_of_business=\"Software development\",\n    registered_capital=\"USD 50000\",\n    website=\"docsprobe.example.com\",\n    email=\"legal@docsprobe.example.com\",\n    phone=\"+1 302 555 0143\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.updateKybCompanyData(\n  \"33333333-4444-5555-6666-777777777777\",\n  \"88888888-9999-aaaa-bbbb-cccccccccccc\",\n  {\n    company_name: \"Docs Probe Corp\",\n    registration_number: \"DPC-001\",\n    country_code: \"US\",\n    incorporation_date: \"2015-04-12\",\n    legal_address: \"1 Example Plaza, Wilmington, DE 19801\",\n    company_type: \"Limited Liability Company\",\n    registry_status: \"active\",\n    verification_status: \"verified\",\n    nature_of_business: \"Software development\",\n    registered_capital: \"USD 50000\",\n    website: \"docsprobe.example.com\",\n    email: \"legal@docsprobe.example.com\",\n    phone: \"+1 302 555 0143\",\n  },\n);\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.UpdateKYBCompanyData(ctx, \"33333333-4444-5555-6666-777777777777\", \"88888888-9999-aaaa-bbbb-cccccccccccc\", didit.SessionsUpdateKYBCompanyDataParams{\n\tCompanyName:        didit.String(\"Docs Probe Corp\"),\n\tRegistrationNumber: didit.String(\"DPC-001\"),\n\tCountryCode:        didit.String(\"US\"),\n\tIncorporationDate:  didit.String(\"2015-04-12\"),\n\tLegalAddress:       didit.String(\"1 Example Plaza, Wilmington, DE 19801\"),\n\tCompanyType:        didit.String(\"Limited Liability Company\"),\n\tRegistryStatus:     didit.Some(didit.SessionsUpdateKYBCompanyDataParamsRegistryStatus(\"active\")),\n\tVerificationStatus: didit.Some(didit.SessionsUpdateKYBCompanyDataParamsVerificationStatus(\"verified\")),\n\tNatureOfBusiness:   didit.String(\"Software development\"),\n\tRegisteredCapital:  didit.String(\"USD 50000\"),\n\tWebsite:            didit.String(\"docsprobe.example.com\"),\n\tEmail:              didit.String(\"legal@docsprobe.example.com\"),\n\tPhone:              didit.String(\"+1 302 555 0143\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.time.LocalDate;\nimport me.didit.Didit;\nimport me.didit.types.SessionsUpdateKybCompanyDataParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().updateKybCompanyData(\"33333333-4444-5555-6666-777777777777\", \"88888888-9999-aaaa-bbbb-cccccccccccc\", SessionsUpdateKybCompanyDataParams.builder()\n        .companyName(\"Docs Probe Corp\")\n        .registrationNumber(\"DPC-001\")\n        .countryCode(\"US\")\n        .incorporationDate(LocalDate.parse(\"2015-04-12\"))\n        .legalAddress(\"1 Example Plaza, Wilmington, DE 19801\")\n        .companyType(\"Limited Liability Company\")\n        .registryStatus(SessionsUpdateKybCompanyDataParams.RegistryStatus.of(\"active\"))\n        .verificationStatus(SessionsUpdateKybCompanyDataParams.VerificationStatus.of(\"verified\"))\n        .natureOfBusiness(\"Software development\")\n        .registeredCapital(\"USD 50000\")\n        .website(\"docsprobe.example.com\")\n        .email(\"legal@docsprobe.example.com\")\n        .phone(\"+1 302 555 0143\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->sessions->updateKybCompanyData('33333333-4444-5555-6666-777777777777', '88888888-9999-aaaa-bbbb-cccccccccccc', [\n    'company_name' => 'Docs Probe Corp',\n    'registration_number' => 'DPC-001',\n    'country_code' => 'US',\n    'incorporation_date' => '2015-04-12',\n    'legal_address' => '1 Example Plaza, Wilmington, DE 19801',\n    'company_type' => 'Limited Liability Company',\n    'registry_status' => 'active',\n    'verification_status' => 'verified',\n    'nature_of_business' => 'Software development',\n    'registered_capital' => 'USD 50000',\n    'website' => 'docsprobe.example.com',\n    'email' => 'legal@docsprobe.example.com',\n    'phone' => '+1 302 555 0143',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.update_kyb_company_data(\n  \"33333333-4444-5555-6666-777777777777\",\n  \"88888888-9999-aaaa-bbbb-cccccccccccc\",\n  company_name: \"Docs Probe Corp\",\n  registration_number: \"DPC-001\",\n  country_code: \"US\",\n  incorporation_date: \"2015-04-12\",\n  legal_address: \"1 Example Plaza, Wilmington, DE 19801\",\n  company_type: \"Limited Liability Company\",\n  registry_status: \"active\",\n  verification_status: \"verified\",\n  nature_of_business: \"Software development\",\n  registered_capital: \"USD 50000\",\n  website: \"docsprobe.example.com\",\n  email: \"legal@docsprobe.example.com\",\n  phone: \"+1 302 555 0143\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.UpdateKybCompanyDataAsync(\"33333333-4444-5555-6666-777777777777\", \"88888888-9999-aaaa-bbbb-cccccccccccc\", new SessionsUpdateKybCompanyDataParams\n{\n    CompanyName = \"Docs Probe Corp\",\n    RegistrationNumber = \"DPC-001\",\n    CountryCode = \"US\",\n    IncorporationDate = \"2015-04-12\",\n    LegalAddress = \"1 Example Plaza, Wilmington, DE 19801\",\n    CompanyType = \"Limited Liability Company\",\n    RegistryStatus = new SessionsUpdateKybCompanyDataParamsRegistryStatus(\"active\"),\n    VerificationStatus = new SessionsUpdateKybCompanyDataParamsVerificationStatus(\"verified\"),\n    NatureOfBusiness = \"Software development\",\n    RegisteredCapital = \"USD 50000\",\n    Website = \"docsprobe.example.com\",\n    Email = \"legal@docsprobe.example.com\",\n    Phone = \"+1 302 555 0143\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/session/{sessionId}/kyb/parties/{partyUuid}/": {
      "patch": {
        "summary": "Lewati (atau wajibkan kembali) pihak kunci pada sesi Verifikasi Bisnis (KYB)",
        "description": "Bebaskan pihak pihak kunci dari verifikasi, atau masukkan kembali ke dalam cakupan. Ini adalah jalur keluar operator untuk pihak yang tidak pernah dapat menyelesaikan pemeriksaannya sendiri - paling sering karena sesi KYC individu yang diserahkan ke UBO atau direktur telah dihapus, yang membekukan status turunan tersebut dan membiarkan KYB tertahan di `Awaiting User` tanpa ada yang bisa memindahkannya.\n\nMenyetel `is_skipped: true` mengeluarkan pihak tersebut dari agregasi pihak kunci dan segera menghitung ulang `KYBKeyPeopleCheck` serta status sesi induk, sehingga sesi bisnis dapat diselesaikan dan kemudian disetujui atau ditolak. Mengirim `is_skipped: false` memasukkan kembali pihak tersebut ke dalam cakupan dan pemeriksaan kembali menunggu pihak tersebut.\n\nTidak seperti lewati yang ditampilkan kepada pemohon di layar pihak kunci yang di-hosting, endpoint ini **tidak** dibatasi oleh pengaturan `allow_skip` peran tersebut - penanda tersebut membatasi apa yang boleh diputuskan oleh pemohon, bukan apa yang boleh dioverride oleh analis Anda. `requires_verification` sengaja dibiarkan tidak berubah, sehingga pihak yang dioverride terbaca sebagai `requires_verification: true` **dan** `is_skipped: true` dan catatan tetap menunjukkan apa yang diminta oleh aturan.\n\nPihak tersebut harus milik sesi dalam jalur (`404` dengan `\"Party does not belong to the given session.\"` jika tidak) dan milik aplikasi Anda. PATCH yang benar-benar mengubah penanda akan memicu [webhook](/id/integration/webhooks) `data.updated` pada sesi bisnis dengan pemicu `console_key_people_skip`; PATCH yang menyetel penanda ke nilainya saat ini tidak melakukan apa pun selain menggemakan kembali pihak tersebut.\n\nMenerima kunci API atau token pengguna konsol; bagaimanapun juga kredensial memerlukan izin `write:businesses`.",
        "operationId": "patch_v3_session_kyb_party_update",
        "x-didit-sdk": {
          "resource": "sessions",
          "method": "update_kyb_party",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Sessions"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "sessionId",
            "in": "path",
            "required": true,
            "description": "UUID dari sesi induk Verifikasi Bisnis (KYB).",
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "33333333-4444-5555-6666-777777777777"
            }
          },
          {
            "name": "partyUuid",
            "in": "path",
            "required": true,
            "description": "UUID pihak kunci yang akan diperbarui (`key_people_checks[].submitted.parties[].uuid` pada keputusan sesi bisnis). Harus dimiliki oleh sesi yang dirujuk oleh `sessionId`.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "0a3f1e2c-7c2f-4a1b-9d55-2f8d2a5d6b41"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "is_skipped"
                ],
                "properties": {
                  "is_skipped": {
                    "type": "boolean",
                    "description": "`true` membebaskan pihak tersebut dari verifikasi sehingga pemeriksaan Pihak Kunci dapat diselesaikan tanpanya; `false` memasukkannya kembali ke dalam cakupan.",
                    "example": true
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Pihak diperbarui (atau dikembalikan tanpa perubahan jika penanda sudah bernilai ini). Mengembalikan data pihak - dengan bentuk yang sama seperti entri `key_people_checks[].submitted.parties[]` pada keputusan sesi bisnis.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Rekaman pihak dari pihak kunci - bentuk yang sama seperti entri `key_people_checks[].submitted.parties[]` pada keputusan sesi bisnis.",
                  "properties": {
                    "uuid": {
                      "type": "string",
                      "format": "uuid",
                      "description": "Pengidentifikasi pihak."
                    },
                    "entity_type": {
                      "type": "string",
                      "enum": [
                        "person",
                        "company"
                      ],
                      "description": "Apakah pihak tersebut adalah individu atau perusahaan."
                    },
                    "name": {
                      "type": "string",
                      "description": "Nama tampilan pihak."
                    },
                    "is_skipped": {
                      "type": "boolean",
                      "description": "Apakah pihak tersebut dikecualikan dari verifikasi."
                    },
                    "requires_verification": {
                      "type": "boolean",
                      "description": "Aturan peran dan ambang batas yang diminta. Dibiarkan tanpa perubahan oleh endpoint ini."
                    },
                    "kyc_session_status": {
                      "type": "string",
                      "nullable": true,
                      "description": "Status sesi KYC individu yang ditautkan, dibekukan pada saat penghapusan jika sesi tersebut dihapus."
                    },
                    "kyc_session_url": {
                      "type": "string",
                      "nullable": true,
                      "description": "Tautan ke sesi KYC individu yang ditautkan. `null` jika tidak ada atau jika sudah dihapus."
                    },
                    "kyc_session_deleted": {
                      "type": "boolean",
                      "description": "Sesi KYC individu yang ditautkan telah dihapus, sehingga tidak akan pernah dapat diselesaikan."
                    },
                    "kyb_sub_session_deleted": {
                      "type": "boolean",
                      "description": "Padanan pihak perusahaan dari `kyc_session_deleted`."
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Kesalahan validasi pada body permintaan. `is_skipped` adalah satu-satunya kolom yang dibaca endpoint ini, dan kolom ini wajib diisi. Kesalahan kolom tiba sebagai `{\"<field>\": [\"<message>\"]}`. Validasi body berjalan *setelah* pencarian pihak, sehingga `is_skipped` yang salah format yang dikirim ke pihak yang tidak ada akan melaporkan `404`, bukan `400`.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing is_skipped": {
                    "summary": "Isi kosong, atau isi yang tidak menyertakan `is_skipped`",
                    "value": {
                      "is_skipped": [
                        "This field is required."
                      ]
                    }
                  },
                  "Non-boolean is_skipped": {
                    "summary": "Nilai bukan boolean — `\"maybe\"`, `2`, `[]`. Boolean ditambah `\"true\"`/`\"false\"`, `1`/`0`, dan `\"yes\"`/`\"no\"` semuanya diterima",
                    "value": {
                      "is_skipped": [
                        "Must be a valid boolean."
                      ]
                    }
                  },
                  "Null is_skipped": {
                    "summary": "`is_skipped` ada tetapi `null`",
                    "value": {
                      "is_skipped": [
                        "This field may not be null."
                      ]
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Kredensial tidak ada atau izin tidak mencukupi. Kunci yang tidak ada mengembalikan `403`; kunci yang salah, dicabut, atau kedaluwarsa mengembalikan `401`.",
            "content": {
              "application/json": {
                "examples": {
                  "Invalid Credentials": {
                    "summary": "x-api-key tidak ada atau tidak valid",
                    "value": {
                      "detail": "Authentication credentials were not provided or are invalid."
                    }
                  },
                  "Missing Privilege": {
                    "summary": "Kredensial tidak memiliki write:businesses",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Pihak tidak dikenal, atau pihak yang terkait dengan sesi yang berbeda. Setiap kasus memiliki pesan `detail` yang berbeda (lihat contoh). Pemeriksaan kredensial dan izin dijalankan sebelum pencarian pihak, sehingga panggilan yang tidak terotorisasi melaporkan `403` alih-alih `404`. Tidak ada pencarian sesi terpisah: `sessionId` tidak dikenal yang dipasangkan dengan pihak Anda akan melaporkan pesan ketidakcocokan.",
            "content": {
              "application/json": {
                "examples": {
                  "Unknown party": {
                    "summary": "Tidak ada pihak dengan UUID ini di aplikasi Anda",
                    "value": {
                      "detail": "Not found."
                    }
                  },
                  "Party / session mismatch": {
                    "summary": "partyUuid ada tetapi terikat pada sesi lain",
                    "value": {
                      "detail": "Party does not belong to the given session."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Batas laju penulisan bersama terlampaui (300 permintaan POST/PATCH/DELETE per menit per kunci API). Periksa header respons `Retry-After` dan `X-RateLimit-*` sebelum mencoba lagi.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Rate limited": {
                    "summary": "Anggaran penulisan habis",
                    "value": {
                      "detail": "Write request rate limit exceeded. You can make up to 300 requests per minute."
                    }
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.update_kyb_party(\n    \"33333333-4444-5555-6666-777777777777\",\n    \"0a3f1e2c-7c2f-4a1b-9d55-2f8d2a5d6b41\",\n    is_skipped=True,\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.updateKybParty(\n  \"33333333-4444-5555-6666-777777777777\",\n  \"0a3f1e2c-7c2f-4a1b-9d55-2f8d2a5d6b41\",\n  {\n    is_skipped: true,\n  },\n);\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.UpdateKYBParty(ctx, \"33333333-4444-5555-6666-777777777777\", \"0a3f1e2c-7c2f-4a1b-9d55-2f8d2a5d6b41\", didit.SessionsUpdateKYBPartyParams{\n\tIsSkipped: true,\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.SessionsUpdateKybPartyParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().updateKybParty(\"33333333-4444-5555-6666-777777777777\", \"0a3f1e2c-7c2f-4a1b-9d55-2f8d2a5d6b41\", SessionsUpdateKybPartyParams.builder()\n        .isSkipped(true)\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->sessions->updateKybParty('33333333-4444-5555-6666-777777777777', '0a3f1e2c-7c2f-4a1b-9d55-2f8d2a5d6b41', [\n    'is_skipped' => true,\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.update_kyb_party(\n  \"33333333-4444-5555-6666-777777777777\",\n  \"0a3f1e2c-7c2f-4a1b-9d55-2f8d2a5d6b41\",\n  is_skipped: true\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.UpdateKybPartyAsync(\"33333333-4444-5555-6666-777777777777\", \"0a3f1e2c-7c2f-4a1b-9d55-2f8d2a5d6b41\", new SessionsUpdateKybPartyParams\n{\n    IsSkipped = true,\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/travel-rule/settings/": {
      "get": {
        "summary": "Dapatkan pengaturan Travel Rule",
        "description": "Baca pengaturan Travel Rule dan profil VASP aplikasi. Secara otomatis membuat baris pengaturan default (nonaktif) dan profil kosong pada pembacaan pertama.",
        "operationId": "getTravelRuleSettings",
        "x-didit-sdk": {
          "resource": "travel_rule",
          "method": "retrieve_settings",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Travel Rule"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET https://verification.didit.me/v3/travel-rule/settings/ \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.travel_rule.retrieve_settings()\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.travelRule.retrieveSettings();\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.TravelRule.RetrieveSettings(ctx)\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.travelRule().retrieveSettings();\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->travelRule->retrieveSettings();\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.travel_rule.retrieve_settings\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.TravelRule.RetrieveSettingsAsync();\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "Pengaturan Travel Rule dan profil VASP saat ini.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TravelRuleSettingsDetail"
                },
                "examples": {
                  "Disabled (default)": {
                    "value": {
                      "is_enabled": false,
                      "jurisdiction": "EU",
                      "name_matching_strictness": "DEFAULT",
                      "confirmation_timeout_hours": 48,
                      "timeout_outcome": "HOLD",
                      "threshold_amount": "0.00",
                      "inbound_auto_accept": true,
                      "allow_self_declaration": true,
                      "allow_screenshot_proof": true,
                      "auto_wallet_verification": true,
                      "vasp_attribution_enabled": true,
                      "legal_name": "",
                      "lei": "",
                      "compliance_email": "",
                      "is_discoverable": true,
                      "counterparty_screening_enabled": false,
                      "sunrise_policy": "",
                      "sunrise_jurisdictions": [
                        "CO",
                        "KH",
                        "VN"
                      ],
                      "non_responsive_policy": "",
                      "travel_address": "",
                      "disabled_networks": [],
                      "networks": {
                        "gtr": {
                          "rail": "GTR",
                          "mode": "unavailable",
                          "state": "didit_onboarding",
                          "reason": "didit_membership_not_live",
                          "platform_available": false,
                          "connected": false,
                          "participant": null,
                          "vasps_reachable": 0,
                          "routed_30d": 0
                        },
                        "trust": {
                          "rail": "TRUST",
                          "mode": "unavailable",
                          "state": "unavailable",
                          "reason": "own_membership_only",
                          "platform_available": false,
                          "connected": false,
                          "participant": null,
                          "vasps_reachable": 0,
                          "routed_30d": 0
                        },
                        "verifyvasp": {
                          "rail": "VERIFYVASP",
                          "mode": "unavailable",
                          "state": "didit_onboarding",
                          "reason": "didit_membership_not_live",
                          "platform_available": false,
                          "connected": false,
                          "participant": null,
                          "vasps_reachable": 0,
                          "routed_30d": 0
                        },
                        "sygna": {
                          "rail": "SYGNA",
                          "mode": "unavailable",
                          "state": "didit_onboarding",
                          "reason": "didit_membership_not_live",
                          "platform_available": false,
                          "connected": false,
                          "participant": null,
                          "vasps_reachable": 0,
                          "routed_30d": 0
                        }
                      },
                      "didit_network": {
                        "listed": false,
                        "missing": [
                          "travel_rule_off",
                          "legal_name_missing",
                          "compliance_email_missing"
                        ],
                        "compliance_email_confirmed": false
                      }
                    }
                  }
                }
              }
            }
          }
        }
      },
      "put": {
        "summary": "Perbarui pengaturan Travel Rule",
        "description": "Upsert pengaturan Travel Rule dan profil VASP aplikasi. Pembaruan parsial — hanya kirim kolom yang ingin Anda ubah. Menyetel `is_enabled: true` memerlukan `legal_name` yang tidak kosong (sudah disimpan atau disertakan dalam permintaan yang sama), jika tidak, akan mengembalikan 400.",
        "operationId": "updateTravelRuleSettings",
        "x-didit-sdk": {
          "resource": "travel_rule",
          "method": "update_settings",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Travel Rule"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TravelRuleSettingsUpdate"
              },
              "example": {
                "is_enabled": true,
                "legal_name": "Origin CASP SL",
                "jurisdiction": "EU",
                "name_matching_strictness": "DEFAULT",
                "confirmation_timeout_hours": 48,
                "timeout_outcome": "HOLD",
                "is_discoverable": true
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X PUT https://verification.didit.me/v3/travel-rule/settings/ \\\n  -H 'x-api-key: YOUR_API_KEY' -H 'Content-Type: application/json' \\\n  -d '{\"is_enabled\": true, \"legal_name\": \"Origin CASP SL\", \"jurisdiction\": \"EU\"}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.travel_rule.update_settings(\n    is_enabled=True,\n    legal_name=\"Origin CASP SL\",\n    jurisdiction=\"EU\",\n    name_matching_strictness=\"DEFAULT\",\n    confirmation_timeout_hours=48,\n    timeout_outcome=\"HOLD\",\n    is_discoverable=True,\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.travelRule.updateSettings({\n  is_enabled: true,\n  legal_name: \"Origin CASP SL\",\n  jurisdiction: \"EU\",\n  name_matching_strictness: \"DEFAULT\",\n  confirmation_timeout_hours: 48,\n  timeout_outcome: \"HOLD\",\n  is_discoverable: true,\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.TravelRule.UpdateSettings(ctx, didit.TravelRuleSettingsUpdate{\n\tIsEnabled:                didit.Bool(true),\n\tLegalName:                didit.String(\"Origin CASP SL\"),\n\tJurisdiction:             didit.String(\"EU\"),\n\tNameMatchingStrictness:   didit.Some(didit.TravelRuleSettingsUpdateNameMatchingStrictness(\"DEFAULT\")),\n\tConfirmationTimeoutHours: didit.Int(48),\n\tTimeoutOutcome:           didit.Some(didit.TravelRuleSettingsUpdateTimeoutOutcome(\"HOLD\")),\n\tIsDiscoverable:           didit.Bool(true),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.TravelRuleSettingsUpdate;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.travelRule().updateSettings(TravelRuleSettingsUpdate.builder()\n        .isEnabled(true)\n        .legalName(\"Origin CASP SL\")\n        .jurisdiction(\"EU\")\n        .nameMatchingStrictness(TravelRuleSettingsUpdate.NameMatchingStrictness.of(\"DEFAULT\"))\n        .confirmationTimeoutHours(48L)\n        .timeoutOutcome(TravelRuleSettingsUpdate.TimeoutOutcome.of(\"HOLD\"))\n        .isDiscoverable(true)\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->travelRule->updateSettings([\n    'is_enabled' => true,\n    'legal_name' => 'Origin CASP SL',\n    'jurisdiction' => 'EU',\n    'name_matching_strictness' => 'DEFAULT',\n    'confirmation_timeout_hours' => 48,\n    'timeout_outcome' => 'HOLD',\n    'is_discoverable' => true,\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.travel_rule.update_settings(\n  is_enabled: true,\n  legal_name: \"Origin CASP SL\",\n  jurisdiction: \"EU\",\n  name_matching_strictness: \"DEFAULT\",\n  confirmation_timeout_hours: 48,\n  timeout_outcome: \"HOLD\",\n  is_discoverable: true\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.TravelRule.UpdateSettingsAsync(new TravelRuleSettingsUpdate\n{\n    IsEnabled = true,\n    LegalName = \"Origin CASP SL\",\n    Jurisdiction = \"EU\",\n    NameMatchingStrictness = new TravelRuleSettingsUpdateNameMatchingStrictness(\"DEFAULT\"),\n    ConfirmationTimeoutHours = 48,\n    TimeoutOutcome = new TravelRuleSettingsUpdateTimeoutOutcome(\"HOLD\"),\n    IsDiscoverable = true,\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "Pengaturan dan profil yang diperbarui, dalam format yang sama seperti GET.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TravelRuleSettingsDetail"
                }
              }
            }
          },
          "400": {
            "description": "Kesalahan validasi, misalnya mengaktifkan tanpa legal_name, sunrise_policy atau non_responsive_policy selain HOLD, REJECT, PROCEED atau kosong, kolom yang tidak dikenal di `matching_rules`, atau pilihan `data_sharing_fields` yang tidak dapat memenuhi kewajiban pengirim dari rezim yurisdiksi Anda (kesalahan dikunci berdasarkan jenis entitas di bawah `data_sharing_fields`).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "legal_name": [
                    "legal_name is required to enable travel rule."
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/v3/travel-rule/settings/compliance-email/confirmation/": {
      "post": {
        "summary": "Kirim konfirmasi email kepatuhan",
        "description": "Mengirimkan tautan konfirmasi sekali pakai ke compliance_email profil VASP Anda. Membuka tautan dan menekan tombol konfirmasi akan mengonfirmasi alamat tersebut, yang diperlukan jaringan Didit sebelum mencantumkan profil Anda. Permintaan baru menggantikan tautan sebelumnya; tautan berhenti berfungsi saat email kepatuhan berubah. Satu email per menit per alamat.",
        "operationId": "sendTravelRuleComplianceEmailConfirmation",
        "x-didit-sdk": {
          "resource": "travel_rule",
          "method": "send_compliance_email_confirmation",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Travel Rule"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST https://verification.didit.me/v3/travel-rule/settings/compliance-email/confirmation/ \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.travel_rule.send_compliance_email_confirmation()\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.travelRule.sendComplianceEmailConfirmation();\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.TravelRule.SendComplianceEmailConfirmation(ctx)\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.travelRule().sendComplianceEmailConfirmation();\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->travelRule->sendComplianceEmailConfirmation();\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.travel_rule.send_compliance_email_confirmation\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.TravelRule.SendComplianceEmailConfirmationAsync();\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "202": {
            "description": "Email konfirmasi telah dikirim.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "sent_to": {
                      "type": "string",
                      "format": "email"
                    }
                  }
                },
                "example": {
                  "sent_to": "compliance@your-vasp.example"
                }
              }
            }
          },
          "400": {
            "description": "Tidak ada email kepatuhan yang disetel, atau email tersebut sudah dikonfirmasi.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "No compliance email": {
                    "value": {
                      "compliance_email": [
                        "Set a compliance email before confirming it."
                      ]
                    }
                  },
                  "Already confirmed": {
                    "value": {
                      "compliance_email": [
                        "This compliance email is already confirmed."
                      ]
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Konfirmasi telah dikirim ke alamat ini kurang dari satu menit yang lalu."
          },
          "503": {
            "description": "Email tidak dapat dikirim. Tidak ada yang berubah; coba lagi sebentar lagi."
          }
        }
      }
    },
    "/v3/travel-rule/wallet-addresses/": {
      "get": {
        "summary": "Daftar entri buku alamat dompet",
        "description": "Daftar buku alamat dompet Travel Rule aplikasi Anda yang berpaginasi, terbaru terlebih dahulu.",
        "operationId": "listTravelRuleWalletAddresses",
        "x-didit-sdk": {
          "resource": "travel_rule.wallet_addresses",
          "method": "list",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Travel Rule"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 50,
              "minimum": 1
            }
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 0,
              "minimum": 0
            }
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET https://verification.didit.me/v3/travel-rule/wallet-addresses/ \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nfor item in client.travel_rule.wallet_addresses.list():\n    print(item)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nfor await (const item of didit.travelRule.walletAddresses.list()) {\n  console.log(item);\n}"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\niter := client.TravelRule.WalletAddresses.ListAutoPaging(ctx, didit.TravelRuleWalletAddressesListParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nfor (var item : client.travelRule().walletAddresses().list()) {\n    System.out.println(item);\n}"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\nforeach ($didit->travelRule->walletAddresses->list() as $item) {\n    print_r($item->toArray());\n}"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.travel_rule.wallet_addresses.list.auto_paging_each do |item|\n  puts item.to_h\nend"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.TravelRule.WalletAddresses.ListAsync())\n{\n    Console.WriteLine(JsonSerializer.Serialize(item));\n}"
          }
        ],
        "responses": {
          "200": {
            "description": "Entri buku alamat dompet terpaginasi.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "count": {
                      "type": "integer"
                    },
                    "next": {
                      "type": "string",
                      "nullable": true
                    },
                    "previous": {
                      "type": "string",
                      "nullable": true
                    },
                    "results": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/WalletAddressEntry"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      },
      "post": {
        "summary": "Daftarkan alamat dompet",
        "description": "Tambahkan entri ke buku alamat dompet Travel Rule Anda agar transfer masuk melalui INTERNAL-rail dapat dicocokkan dengannya.",
        "operationId": "createTravelRuleWalletAddress",
        "x-didit-sdk": {
          "resource": "travel_rule.wallet_addresses",
          "method": "create",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Travel Rule"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WalletAddressEntryCreate"
              },
              "example": {
                "address": "0xBeneficiaryWallet01",
                "chain": "ETH",
                "holder_name": "Ana Diaz",
                "holder_vendor_data": "user-042",
                "self_declared": true
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST https://verification.didit.me/v3/travel-rule/wallet-addresses/ \\\n  -H 'x-api-key: YOUR_API_KEY' -H 'Content-Type: application/json' \\\n  -d '{\"address\": \"0xBeneficiaryWallet01\", \"chain\": \"ETH\", \"holder_name\": \"Ana Diaz\", \"self_declared\": true}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.travel_rule.wallet_addresses.create(\n    address=\"0xBeneficiaryWallet01\",\n    chain=\"ETH\",\n    holder_vendor_data=\"user-042\",\n    holder_name=\"Ana Diaz\",\n    self_declared=True,\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.travelRule.walletAddresses.create({\n  address: \"0xBeneficiaryWallet01\",\n  chain: \"ETH\",\n  holder_vendor_data: \"user-042\",\n  holder_name: \"Ana Diaz\",\n  self_declared: true,\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.TravelRule.WalletAddresses.Create(ctx, didit.WalletAddressEntryCreate{\n\tAddress:          \"0xBeneficiaryWallet01\",\n\tChain:            didit.String(\"ETH\"),\n\tHolderVendorData: didit.String(\"user-042\"),\n\tHolderName:       didit.String(\"Ana Diaz\"),\n\tSelfDeclared:     didit.Bool(true),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.WalletAddressEntryCreate;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.travelRule().walletAddresses().create(WalletAddressEntryCreate.builder()\n        .address(\"0xBeneficiaryWallet01\")\n        .chain(\"ETH\")\n        .holderVendorData(\"user-042\")\n        .holderName(\"Ana Diaz\")\n        .selfDeclared(true)\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->travelRule->walletAddresses->create([\n    'address' => '0xBeneficiaryWallet01',\n    'chain' => 'ETH',\n    'holder_vendor_data' => 'user-042',\n    'holder_name' => 'Ana Diaz',\n    'self_declared' => true,\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.travel_rule.wallet_addresses.create(\n  address: \"0xBeneficiaryWallet01\",\n  chain: \"ETH\",\n  holder_vendor_data: \"user-042\",\n  holder_name: \"Ana Diaz\",\n  self_declared: true\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.TravelRule.WalletAddresses.CreateAsync(new WalletAddressEntryCreate\n{\n    Address = \"0xBeneficiaryWallet01\",\n    Chain = \"ETH\",\n    HolderVendorData = \"user-042\",\n    HolderName = \"Ana Diaz\",\n    SelfDeclared = true,\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "201": {
            "description": "Entri yang dibuat.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WalletAddressEntry"
                }
              }
            }
          },
          "400": {
            "description": "Dompet duplikat (alamat, chain, dan memo) untuk aplikasi ini, memo atau X-address yang tidak dapat dibawa oleh chain, `address` tidak ada, `travel_address` tidak valid, `self_declared: true` saat `allow_self_declaration` nonaktif, atau `self_declared: true` saat `ownership_validation_mode` bernilai `FULL`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "examples": {
                  "Duplicate entry": {
                    "value": {
                      "address": [
                        "A wallet address entry with this address and chain already exists."
                      ]
                    }
                  },
                  "Invalid travel address": {
                    "value": {
                      "travel_address": [
                        "Invalid travel address."
                      ]
                    }
                  },
                  "Self-declaration disabled": {
                    "value": {
                      "self_declared": [
                        "Self-declared ownership is disabled for this application."
                      ]
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v3/travel-rule/wallet-addresses/{entry_uuid}/": {
      "patch": {
        "summary": "Perbarui metadata pemegang alamat",
        "description": "Pembaruan parsial untuk holder_name, holder_vendor_data, entity_type, dan travel_address. Menyetel travel_address akan melampirkan alamat perutean TRP ke entri tersebut; nilai yang tidak valid akan ditolak dengan 400. Respons hanya mengembalikan keempat kolom ini.",
        "operationId": "updateTravelRuleWalletAddress",
        "x-didit-sdk": {
          "resource": "travel_rule.wallet_addresses",
          "method": "update",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Travel Rule"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "entry_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WalletAddressEntryUpdate"
              },
              "example": {
                "holder_name": "Ana Updated",
                "travel_address": "ta2ih1MicegQ3JqiKz9xT89KsSuwaDJYw8DgzmeSEp1h9tduJcNDZ5SgKLEHeyGMcS1s2HgbM6undFrMQknhM5aTXw3G9KBzi16hx"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X PATCH https://verification.didit.me/v3/travel-rule/wallet-addresses/{entry_uuid}/ \\\n  -H 'x-api-key: YOUR_API_KEY' -H 'Content-Type: application/json' \\\n  -d '{\"holder_name\": \"Ana Updated\", \"travel_address\": \"ta2ih1MicegQ3JqiKz9xT89KsSuwaDJYw8DgzmeSEp1h9tduJcNDZ5SgKLEHeyGMcS1s2HgbM6undFrMQknhM5aTXw3G9KBzi16hx\"}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.travel_rule.wallet_addresses.update(\n    \"11111111-2222-3333-4444-555555555555\",\n    holder_name=\"Ana Updated\",\n    travel_address=\"ta2ih1MicegQ3JqiKz9xT89KsSuwaDJYw8DgzmeSEp1h9tduJcNDZ5SgKLEHeyGMcS1s2HgbM6undFrMQknhM5aTXw3G9KBzi16hx\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.travelRule.walletAddresses.update(\"11111111-2222-3333-4444-555555555555\", {\n  holder_name: \"Ana Updated\",\n  travel_address: \"ta2ih1MicegQ3JqiKz9xT89KsSuwaDJYw8DgzmeSEp1h9tduJcNDZ5SgKLEHeyGMcS1s2HgbM6undFrMQknhM5aTXw3G9KBzi16hx\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.TravelRule.WalletAddresses.Update(ctx, \"11111111-2222-3333-4444-555555555555\", didit.WalletAddressEntryUpdateParam{\n\tHolderName:    didit.String(\"Ana Updated\"),\n\tTravelAddress: didit.String(\"ta2ih1MicegQ3JqiKz9xT89KsSuwaDJYw8DgzmeSEp1h9tduJcNDZ5SgKLEHeyGMcS1s2HgbM6undFrMQknhM5aTXw3G9KBzi16hx\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.WalletAddressEntryUpdate;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.travelRule().walletAddresses().update(\"11111111-2222-3333-4444-555555555555\", WalletAddressEntryUpdate.builder()\n        .holderName(\"Ana Updated\")\n        .travelAddress(\"ta2ih1MicegQ3JqiKz9xT89KsSuwaDJYw8DgzmeSEp1h9tduJcNDZ5SgKLEHeyGMcS1s2HgbM6undFrMQknhM5aTXw3G9KBzi16hx\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->travelRule->walletAddresses->update('11111111-2222-3333-4444-555555555555', [\n    'holder_name' => 'Ana Updated',\n    'travel_address' => 'ta2ih1MicegQ3JqiKz9xT89KsSuwaDJYw8DgzmeSEp1h9tduJcNDZ5SgKLEHeyGMcS1s2HgbM6undFrMQknhM5aTXw3G9KBzi16hx',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.travel_rule.wallet_addresses.update(\n  \"11111111-2222-3333-4444-555555555555\",\n  holder_name: \"Ana Updated\",\n  travel_address: \"ta2ih1MicegQ3JqiKz9xT89KsSuwaDJYw8DgzmeSEp1h9tduJcNDZ5SgKLEHeyGMcS1s2HgbM6undFrMQknhM5aTXw3G9KBzi16hx\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.TravelRule.WalletAddresses.UpdateAsync(\"11111111-2222-3333-4444-555555555555\", new WalletAddressEntryUpdate\n{\n    HolderName = \"Ana Updated\",\n    TravelAddress = \"ta2ih1MicegQ3JqiKz9xT89KsSuwaDJYw8DgzmeSEp1h9tduJcNDZ5SgKLEHeyGMcS1s2HgbM6undFrMQknhM5aTXw3G9KBzi16hx\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "Kolom yang diperbarui.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WalletAddressEntryUpdate"
                }
              }
            }
          },
          "400": {
            "description": "`travel_address` bukan Travel Address yang valid.",
            "content": {
              "application/json": {
                "examples": {
                  "Invalid travel address": {
                    "value": {
                      "travel_address": [
                        "Invalid travel address."
                      ]
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Entri tidak dikenal atau dihapus."
          }
        }
      },
      "delete": {
        "summary": "Hapus alamat dompet",
        "description": "Menghapus entri beserta bukti kepemilikan dan tangkapan layar yang disimpannya. Entri ini langsung berhenti mencocokkan transfer baru dan alamat tersebut dibebaskan untuk pendaftaran ulang. Transfer yang telah menggunakan dompet tersebut tetap menyimpan catatannya sendiri dan menampilkan data yang sama. Penghapusan tidak dapat dibatalkan.",
        "operationId": "deleteTravelRuleWalletAddress",
        "x-didit-sdk": {
          "resource": "travel_rule.wallet_addresses",
          "method": "delete",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Travel Rule"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "entry_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X DELETE https://verification.didit.me/v3/travel-rule/wallet-addresses/{entry_uuid}/ \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nclient.travel_rule.wallet_addresses.delete(\n    \"11111111-2222-3333-4444-555555555555\",\n)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nawait didit.travelRule.walletAddresses.delete(\"11111111-2222-3333-4444-555555555555\");"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nif err := client.TravelRule.WalletAddresses.Delete(ctx, \"11111111-2222-3333-4444-555555555555\"); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nclient.travelRule().walletAddresses().delete(\"11111111-2222-3333-4444-555555555555\");"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$didit->travelRule->walletAddresses->delete('11111111-2222-3333-4444-555555555555');"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.travel_rule.wallet_addresses.delete(\"11111111-2222-3333-4444-555555555555\")"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nawait client.TravelRule.WalletAddresses.DeleteAsync(\"11111111-2222-3333-4444-555555555555\");"
          }
        ],
        "responses": {
          "204": {
            "description": "Dihapus."
          },
          "404": {
            "description": "Entri tidak dikenal atau sudah dihapus."
          },
          "503": {
            "description": "`wallet_address_deletion_incomplete`: file yang disimpan tidak dapat dihapus, sehingga penghapusan terhenti sebelum selesai. Entri buku alamat masih ada; coba lagi permintaan yang sama untuk menyelesaikannya.",
            "content": {
              "application/json": {
                "example": {
                  "detail": "A stored file could not be deleted, so the deletion stopped before it finished. Try again.",
                  "code": "wallet_address_deletion_incomplete"
                }
              }
            }
          }
        }
      }
    },
    "/v3/travel-rule/vasps/": {
      "get": {
        "summary": "Cari direktori VASP",
        "description": "Pencarian direktori VASP terpaginasi dan diurutkan berdasarkan nama: entri direktori bersama, yang dibangun Didit dari daftar sementara MiCA ESMA, direktori publik TRISA, registri global LEI, dan kurasi internalnya sendiri, ditambah para anggota jaringan Didit. Setiap baris memuat rute yang dimiliki aplikasi Anda ke entitas tersebut saat ini. Profil aplikasi Anda sendiri tidak pernah dicantumkan. Baris juga memuat penilaian uji tuntas bersama serta keputusan, skrining entitas, dan kuesioner aplikasi Anda sendiri.",
        "operationId": "listTravelRuleVasps",
        "tags": [
          "Travel Rule"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "search",
            "in": "query",
            "schema": {
              "type": "string",
              "maxLength": 255
            },
            "description": "Fragmen nama atau alias (tidak peka huruf besar/kecil), LEI yang tepat, atau domain (example.com atau URL di dalamnya). Anggota jaringan Didit dicocokkan berdasarkan nama resmi, LEI, atau domain email kepatuhan mereka."
          },
          {
            "name": "network",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "GTR",
                "TRUST",
                "VERIFYVASP",
                "SYGNA",
                "TRISA"
              ]
            },
            "description": "Hanya entri direktori yang saat ini tercantum dalam direktori anggota suatu jaringan."
          },
          {
            "name": "jurisdiction",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Kode negara ISO 3166 alpha-2 atau alpha-3. Mengembalikan 400 untuk hal lainnya."
          },
          {
            "name": "reachable",
            "in": "query",
            "schema": {
              "type": "boolean"
            },
            "description": "true: hanya VASP yang dapat dijangkau aplikasi Anda melalui rute yang tersedia (termasuk anggota jaringan Didit). false: hanya entri direktori yang tidak dapat dijangkau saat ini."
          },
          {
            "name": "kind",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "directory",
                "didit"
              ]
            },
            "description": "Hanya entri direktori, atau hanya anggota jaringan Didit."
          },
          {
            "name": "risk",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "LOW",
                "MEDIUM",
                "HIGH"
              ]
            },
            "description": "Hanya entri direktori yang risk_level-nya berada dalam rentang ini. Anggota jaringan Didit, yang tidak diberi skor, tidak pernah cocok."
          },
          {
            "name": "responsiveness",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "RESPONSIVE",
                "UNRESPONSIVE",
                "UNKNOWN"
              ]
            },
            "description": "Hanya entri direktori yang responsiveness.status-nya memiliki nilai ini. Anggota jaringan Didit tidak pernah cocok."
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 50,
              "minimum": 1
            }
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 0,
              "minimum": 0
            }
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/travel-rule/vasps/?search=counterparty&reachable=true' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nfor item in client.travel_rule.list_vasps():\n    print(item)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nfor await (const item of didit.travelRule.listVasps()) {\n  console.log(item);\n}"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\niter := client.TravelRule.ListVASPsAutoPaging(ctx, didit.TravelRuleListVASPsParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nfor (var item : client.travelRule().listVasps()) {\n    System.out.println(item);\n}"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\nforeach ($didit->travelRule->listVasps() as $item) {\n    print_r($item->toArray());\n}"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.travel_rule.list_vasps.auto_paging_each do |item|\n  puts item.to_h\nend"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.TravelRule.ListVaspsAsync())\n{\n    Console.WriteLine(JsonSerializer.Serialize(item));\n}"
          }
        ],
        "responses": {
          "200": {
            "description": "Hasil direktori VASP terpaginasi dan diurutkan berdasarkan nama.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "count": {
                      "type": "integer"
                    },
                    "next": {
                      "type": "string",
                      "nullable": true
                    },
                    "previous": {
                      "type": "string",
                      "nullable": true
                    },
                    "results": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/VaspDirectoryEntry"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Filter tidak valid: body menyebutkan nama setiap kolom, misalnya jaringan, kode negara, tingkat risiko, atau status responsivitas yang tidak dikenal.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "jurisdiction": [
                    "Use an ISO 3166 alpha-2 or alpha-3 country code."
                  ],
                  "network": [
                    "\"SWIFT\" is not a valid choice."
                  ]
                }
              }
            }
          }
        },
        "x-didit-sdk": {
          "resource": "travel_rule",
          "method": "list_vasps",
          "auth": "api_key",
          "server": true
        }
      }
    },
    "/v3/travel-rule/vasps/{vasp_id}/": {
      "get": {
        "summary": "Dapatkan entri direktori VASP",
        "description": "Satu entri direktori atau anggota jaringan Didit berdasarkan id yang dikembalikan oleh pencarian, dengan kolom yang sama dan rute yang dimiliki aplikasi Anda ke entri tersebut.",
        "operationId": "getTravelRuleVasp",
        "x-didit-sdk": {
          "resource": "travel_rule",
          "method": "retrieve_vasp",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Travel Rule"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "vasp_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "ID dari baris GET /v3/travel-rule/vasps/."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET https://verification.didit.me/v3/travel-rule/vasps/{vasp_id}/ \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.travel_rule.retrieve_vasp(\n    \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.travelRule.retrieveVasp(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.TravelRule.RetrieveVASP(ctx, \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.travelRule().retrieveVasp(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->travelRule->retrieveVasp('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.travel_rule.retrieve_vasp(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.TravelRule.RetrieveVaspAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "Entri.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VaspDirectoryEntry"
                }
              }
            }
          },
          "404": {
            "description": "Tidak ada entri atau anggota jaringan Didit terdaftar yang memiliki id ini.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "detail": "No directory entry has this id."
                }
              }
            }
          }
        }
      }
    },
    "/v3/travel-rule/vasps/{vasp_id}/decision/": {
      "get": {
        "summary": "Dapatkan keputusan Anda tentang VASP",
        "description": "Keputusan aplikasi Anda terhadap pihak lawan (entri direktori atau anggota jaringan Didit): approved, restricted, atau blocked. Entitas dari merek yang tidak memiliki keputusan tersendiri mengikuti keputusan merek tersebut, yang disebutkan dalam inherited_from. Bersifat privat untuk aplikasi Anda.",
        "operationId": "getTravelRuleVaspDecision",
        "x-didit-sdk": {
          "resource": "travel_rule",
          "method": "retrieve_vasp_decision",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Travel Rule"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "vasp_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "ID dari baris GET /v3/travel-rule/vasps/: entri direktori atau anggota jaringan Didit."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET https://verification.didit.me/v3/travel-rule/vasps/{vasp_id}/decision/ \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.travel_rule.retrieve_vasp_decision(\n    \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.travelRule.retrieveVaspDecision(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.TravelRule.RetrieveVASPDecision(ctx, \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.travelRule().retrieveVaspDecision(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->travelRule->retrieveVaspDecision('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.travel_rule.retrieve_vasp_decision(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.TravelRule.RetrieveVaspDecisionAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "Keputusan yang berlaku, atau null.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TravelRuleCounterpartyDecisionResponse"
                },
                "examples": {
                  "Own decision": {
                    "value": {
                      "decision": {
                        "decision": "APPROVED",
                        "reason": "Licensed in DE, questionnaire reviewed",
                        "decided_by": "",
                        "updated_at": "2026-10-14T10:05:00Z",
                        "inherited_from": null
                      }
                    }
                  },
                  "Inherited from the brand": {
                    "value": {
                      "decision": {
                        "decision": "BLOCKED",
                        "reason": "Group refused after review",
                        "decided_by": "",
                        "updated_at": "2026-10-14T10:05:00Z",
                        "inherited_from": {
                          "id": "5e4d3c2b-1a0f-4e9d-8c7b-6a5f4e3d2c1b",
                          "name": "Example Group"
                        }
                      }
                    }
                  },
                  "No decision": {
                    "value": {
                      "decision": null
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Tidak ada entri direktori atau anggota jaringan Didit terdaftar yang memiliki id ini. Profil VASP Anda sendiri tidak pernah menjadi pihak lawan Anda.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "detail": "No directory entry or Didit network member has this id."
                }
              }
            }
          }
        }
      },
      "put": {
        "summary": "Tetapkan keputusan Anda tentang VASP",
        "description": "Buat atau ubah keputusan aplikasi Anda mengenai pihak lawan: APPROVED, RESTRICTED, atau BLOCKED, dengan alasan opsional. Tindakan ini tidak pernah mengubah entri direktori bersama dan hanya berlaku melalui aturan transaksi Anda (counterparty_dd_status). Keputusan pada suatu merek juga mencakup setiap entitasnya yang belum memiliki keputusannya sendiri.",
        "operationId": "updateTravelRuleVaspDecision",
        "x-didit-sdk": {
          "resource": "travel_rule",
          "method": "update_vasp_decision",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Travel Rule"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "vasp_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "ID dari baris GET /v3/travel-rule/vasps/: entri direktori atau anggota jaringan Didit."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TravelRuleCounterpartyDecisionRequest"
              },
              "example": {
                "decision": "BLOCKED",
                "reason": "Unlicensed in its home jurisdiction"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X PUT https://verification.didit.me/v3/travel-rule/vasps/{vasp_id}/decision/ \\\n  -H 'x-api-key: YOUR_API_KEY' -H 'Content-Type: application/json' \\\n  -d '{\"decision\": \"BLOCKED\", \"reason\": \"Unlicensed in its home jurisdiction\"}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.travel_rule.update_vasp_decision(\n    \"11111111-2222-3333-4444-555555555555\",\n    decision=\"BLOCKED\",\n    reason=\"Unlicensed in its home jurisdiction\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.travelRule.updateVaspDecision(\"11111111-2222-3333-4444-555555555555\", {\n  decision: \"BLOCKED\",\n  reason: \"Unlicensed in its home jurisdiction\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.TravelRule.UpdateVASPDecision(ctx, \"11111111-2222-3333-4444-555555555555\", didit.TravelRuleCounterpartyDecisionRequest{\n\tDecision: \"BLOCKED\",\n\tReason:   didit.String(\"Unlicensed in its home jurisdiction\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.TravelRuleCounterpartyDecisionRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.travelRule().updateVaspDecision(\"11111111-2222-3333-4444-555555555555\", TravelRuleCounterpartyDecisionRequest.builder()\n        .decision(TravelRuleCounterpartyDecisionRequest.Decision.of(\"BLOCKED\"))\n        .reason(\"Unlicensed in its home jurisdiction\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->travelRule->updateVaspDecision('11111111-2222-3333-4444-555555555555', [\n    'decision' => 'BLOCKED',\n    'reason' => 'Unlicensed in its home jurisdiction',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.travel_rule.update_vasp_decision(\n  \"11111111-2222-3333-4444-555555555555\",\n  decision: \"BLOCKED\",\n  reason: \"Unlicensed in its home jurisdiction\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.TravelRule.UpdateVaspDecisionAsync(\"11111111-2222-3333-4444-555555555555\", new TravelRuleCounterpartyDecisionRequest\n{\n    Decision = \"BLOCKED\",\n    Reason = \"Unlicensed in its home jurisdiction\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "Keputusan sebagaimana berlaku saat ini.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TravelRuleCounterpartyDecisionResponse"
                },
                "example": {
                  "decision": {
                    "decision": "BLOCKED",
                    "reason": "Unlicensed in its home jurisdiction",
                    "decided_by": "",
                    "updated_at": "2026-10-14T10:05:00Z",
                    "inherited_from": null
                  }
                }
              }
            }
          },
          "400": {
            "description": "Keputusan tidak ada atau bukan salah satu dari APPROVED, RESTRICTED, atau BLOCKED, atau alasannya lebih panjang dari 255 karakter.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "decision": [
                    "\"MAYBE\" is not a valid choice."
                  ]
                }
              }
            }
          },
          "404": {
            "description": "Tidak ada entri direktori atau anggota jaringan Didit terdaftar yang memiliki id ini. Profil VASP Anda sendiri tidak pernah menjadi pihak lawan Anda.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "detail": "No directory entry or Didit network member has this id."
                }
              }
            }
          }
        }
      },
      "delete": {
        "summary": "Hapus keputusan Anda terhadap VASP",
        "description": "Hapus keputusan aplikasi Anda sendiri terhadap pihak lawan. Respons menampilkan keputusan yang berlaku setelahnya: null, atau untuk entitas dari suatu merek berlaku keputusan merek tersebut, yang kembali diikuti oleh entitas.",
        "operationId": "clearTravelRuleVaspDecision",
        "x-didit-sdk": {
          "resource": "travel_rule",
          "method": "clear_vasp_decision",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Travel Rule"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "vasp_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "ID dari baris GET /v3/travel-rule/vasps/: entri direktori atau anggota jaringan Didit."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X DELETE https://verification.didit.me/v3/travel-rule/vasps/{vasp_id}/decision/ \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.travel_rule.clear_vasp_decision(\n    \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.travelRule.clearVaspDecision(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.TravelRule.ClearVASPDecision(ctx, \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.travelRule().clearVaspDecision(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->travelRule->clearVaspDecision('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.travel_rule.clear_vasp_decision(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.TravelRule.ClearVaspDecisionAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "Keputusan telah dihapus; isi menampilkan keputusan yang berlaku sekarang.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TravelRuleCounterpartyDecisionResponse"
                },
                "example": {
                  "decision": null
                }
              }
            }
          },
          "404": {
            "description": "Tidak ada pihak lawan yang memiliki id ini, atau aplikasi Anda tidak memiliki keputusan sendiri terkait hal tersebut (keputusan yang hanya diwarisi dari mereknya tidak dapat dihapus di sini: hapus keputusan merek tersebut).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Unknown id": {
                    "value": {
                      "detail": "No directory entry or Didit network member has this id."
                    }
                  },
                  "No decision of its own": {
                    "value": {
                      "detail": "This application has no decision of its own on this counterparty."
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v3/travel-rule/vasps/{vasp_id}/screening/": {
      "get": {
        "summary": "Dapatkan skrining entitas VASP",
        "description": "Menentukan apakah skrining pihak lawan aktif untuk aplikasi Anda, biaya satu kali skrining bagi organisasi Anda, berapa lama hasil tetap terkini, dan skrining sanksi serta media negatif terbaru Anda untuk pihak lawan. Membacanya gratis.",
        "operationId": "getTravelRuleVaspScreening",
        "x-didit-sdk": {
          "resource": "travel_rule",
          "method": "retrieve_vasp_screening",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Travel Rule"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "vasp_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "ID dari baris GET /v3/travel-rule/vasps/: entri direktori atau anggota jaringan Didit."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET https://verification.didit.me/v3/travel-rule/vasps/{vasp_id}/screening/ \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.travel_rule.retrieve_vasp_screening(\n    \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.travelRule.retrieveVaspScreening(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.TravelRule.RetrieveVASPScreening(ctx, \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.travelRule().retrieveVaspScreening(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->travelRule->retrieveVaspScreening('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.travel_rule.retrieve_vasp_screening(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.TravelRule.RetrieveVaspScreeningAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "Pengaturan skrining Anda, harganya, dan skrining terbaru Anda.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TravelRuleCounterpartyScreeningStatus"
                },
                "example": {
                  "enabled": true,
                  "price": "0.20",
                  "fresh_days": 30,
                  "screening": {
                    "id": "7a1d2c3b-4e5f-4a6b-8c7d-9e0f1a2b3c4d",
                    "status": "Approved",
                    "total_hits": 0,
                    "score": null,
                    "screened_at": "2026-10-14T09:58:00Z",
                    "fresh": true,
                    "flagged": false
                  }
                }
              }
            }
          },
          "403": {
            "description": "Kontrak organisasi Anda belum mengonfigurasi tarif untuk skrining pihak lawan.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "detail": "No contract rate is configured for this usage type."
                }
              }
            }
          },
          "404": {
            "description": "Tidak ada entri direktori atau anggota jaringan Didit terdaftar yang memiliki id ini. Profil VASP Anda sendiri tidak pernah menjadi pihak lawan Anda.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "detail": "No directory entry or Didit network member has this id."
                }
              }
            }
          }
        }
      },
      "post": {
        "summary": "Lakukan skrining VASP",
        "description": "Skrining entitas pihak lawan terhadap sanksi dan media negatif untuk aplikasi Anda. Keikutsertaan: counterparty_screening_enabled harus aktif di pengaturan Travel Rule Anda. Setiap skrining baru ditagih sesuai harga Skrining AML Perusahaan milik organisasi Anda; skrining yang berusia kurang dari 30 hari akan dikembalikan sebagai gantinya (200, tidak ditagih) kecuali Anda mengirimkan refresh: true. Satu skrining pihak lawan berjalan dalam satu waktu per aplikasi. Hasilnya bersifat privat untuk aplikasi Anda. Aplikasi sandbox tidak pernah diskrining.",
        "operationId": "screenTravelRuleVasp",
        "x-didit-sdk": {
          "resource": "travel_rule",
          "method": "screen_vasp",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Travel Rule"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "vasp_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "ID dari baris GET /v3/travel-rule/vasps/: entri direktori atau anggota jaringan Didit."
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TravelRuleCounterpartyScreeningRequest"
              },
              "example": {
                "refresh": false
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST https://verification.didit.me/v3/travel-rule/vasps/{vasp_id}/screening/ \\\n  -H 'x-api-key: YOUR_API_KEY' -H 'Content-Type: application/json' \\\n  -d '{\"refresh\": false}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.travel_rule.screen_vasp(\n    \"11111111-2222-3333-4444-555555555555\",\n    refresh=False,\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.travelRule.screenVasp(\"11111111-2222-3333-4444-555555555555\", {\n  refresh: false,\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.TravelRule.ScreenVASP(ctx, \"11111111-2222-3333-4444-555555555555\", didit.TravelRuleCounterpartyScreeningRequest{\n\tRefresh: didit.Bool(false),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.TravelRuleCounterpartyScreeningRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.travelRule().screenVasp(\"11111111-2222-3333-4444-555555555555\", TravelRuleCounterpartyScreeningRequest.builder()\n        .refresh(false)\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->travelRule->screenVasp('11111111-2222-3333-4444-555555555555', [\n    'refresh' => false,\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.travel_rule.screen_vasp(\n  \"11111111-2222-3333-4444-555555555555\",\n  refresh: false\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.TravelRule.ScreenVaspAsync(\"11111111-2222-3333-4444-555555555555\", new TravelRuleCounterpartyScreeningRequest\n{\n    Refresh = false,\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "Skrining baru sudah ada dan telah dikembalikan. Tidak ada biaya yang ditagihkan.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TravelRuleCounterpartyScreeningResult"
                },
                "example": {
                  "outcome": "reused",
                  "screening": {
                    "id": "7a1d2c3b-4e5f-4a6b-8c7d-9e0f1a2b3c4d",
                    "status": "Approved",
                    "total_hits": 0,
                    "score": null,
                    "screened_at": "2026-10-14T09:58:00Z",
                    "fresh": true,
                    "flagged": false
                  }
                }
              }
            }
          },
          "201": {
            "description": "Skrining baru telah dijalankan dan ditagihkan.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TravelRuleCounterpartyScreeningResult"
                },
                "example": {
                  "outcome": "screened",
                  "screening": {
                    "id": "7a1d2c3b-4e5f-4a6b-8c7d-9e0f1a2b3c4d",
                    "status": "In Review",
                    "total_hits": 2,
                    "score": 85.0,
                    "screened_at": "2026-10-14T09:58:00Z",
                    "fresh": true,
                    "flagged": true
                  }
                }
              }
            }
          },
          "400": {
            "description": "Isi body tidak valid, atau pihak lawan tidak memiliki nama untuk diskrining.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "detail": [
                    "This counterparty has no name to screen."
                  ]
                }
              }
            }
          },
          "403": {
            "description": "Saldo organisasi Anda tidak mencukupi untuk skrining (kode insufficient_credits; tidak ada yang dijalankan dan tidak ada yang ditagih), atau kontrak Anda belum mengonfigurasi tarif untuknya.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "detail": "You don't have enough credits to perform this request. Please top up at https://business.didit.me",
                  "code": "insufficient_credits"
                }
              }
            }
          },
          "404": {
            "description": "Tidak ada entri direktori atau anggota jaringan Didit terdaftar yang memiliki id ini. Profil VASP Anda sendiri tidak pernah menjadi pihak lawan Anda.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "detail": "No directory entry or Didit network member has this id."
                }
              }
            }
          },
          "409": {
            "description": "Tidak ada yang berjalan dan tidak ada yang ditagihkan: skrining pihak lawan dinonaktifkan untuk aplikasi Anda, aplikasi berstatus sandbox, atau skrining pihak lawan ini sedang berjalan.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Screening off": {
                    "value": {
                      "detail": "Counterparty screening is turned off. Enable it in the Travel Rule settings first."
                    }
                  },
                  "Sandbox application": {
                    "value": {
                      "detail": "Counterparty screening does not run for sandbox applications."
                    }
                  },
                  "Already running": {
                    "value": {
                      "detail": "A screening of this counterparty is already running. Try again in a moment."
                    }
                  }
                }
              }
            }
          },
          "502": {
            "description": "Skrining tidak dapat diselesaikan. Tidak ada biaya yang ditagihkan; coba lagi sebentar lagi.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "detail": "The screening provider did not answer. Try again in a moment."
                }
              }
            }
          }
        }
      }
    },
    "/v3/travel-rule/vasps/{vasp_id}/questionnaires/": {
      "get": {
        "summary": "Daftar kuesioner uji tuntas dengan VASP",
        "description": "Setiap kuesioner uji tuntas yang dikirimkan aplikasi Anda ke pihak lawan, yang terbaru terlebih dahulu, beserta statusnya dan, setelah dijawab, jawabannya. Bersifat privat untuk aplikasi Anda.",
        "operationId": "listTravelRuleVaspQuestionnaires",
        "x-didit-sdk": {
          "resource": "travel_rule",
          "method": "list_vasp_questionnaires",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Travel Rule"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "vasp_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "ID dari baris GET /v3/travel-rule/vasps/: entri direktori atau anggota jaringan Didit."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET https://verification.didit.me/v3/travel-rule/vasps/{vasp_id}/questionnaires/ \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.travel_rule.list_vasp_questionnaires(\n    \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.travelRule.listVaspQuestionnaires(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.TravelRule.ListVASPQuestionnaires(ctx, \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.travelRule().listVaspQuestionnaires(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->travelRule->listVaspQuestionnaires('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.travel_rule.list_vasp_questionnaires(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.TravelRule.ListVaspQuestionnairesAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "Kuesioner Anda dengan pihak lawan ini.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TravelRuleCounterpartyQuestionnaireList"
                },
                "example": {
                  "questionnaires": [
                    {
                      "id": "3f9e8d7c-6b5a-4c3d-9e2f-1a0b9c8d7e6f",
                      "status": "SENT",
                      "form_version": "1",
                      "sent_to": "travelrule@counterparty.example",
                      "sent_at": "2026-10-14T10:00:00Z",
                      "expires_at": "2026-11-13T10:00:00Z",
                      "answered_at": null,
                      "valid_until": null,
                      "current": false,
                      "answers": {}
                    },
                    {
                      "id": "8b7a6c5d-4e3f-4a2b-9c1d-0e9f8a7b6c5d",
                      "status": "ANSWERED",
                      "form_version": "1",
                      "sent_to": "travelrule@counterparty.example",
                      "sent_at": "2026-09-02T08:00:00Z",
                      "expires_at": "2026-10-02T08:00:00Z",
                      "answered_at": "2026-09-04T15:20:00Z",
                      "valid_until": "2027-09-04T15:20:00Z",
                      "current": true,
                      "answers": {
                        "legal_name": "Example Counterparty VASP, incorporated in the example jurisdiction.",
                        "licensing": "Crypto-asset service provider authorised under MiCA by its national regulator, licence active.",
                        "jurisdictions": "EU and EEA. We do not serve the United States.",
                        "aml_program": "Written AML/CFT policy, annual independent review, last completed in March 2026.",
                        "compliance_officer": "Head of Compliance, reachable at compliance@counterparty.example.",
                        "sanctions_screening": "Customers at onboarding and daily; counterparties on every transfer.",
                        "transaction_monitoring": "Rule-based monitoring with analyst review; suspicious activity reports filed with the FIU.",
                        "travel_rule": "TRP and email; we answer requests within one business day.",
                        "custody": "Segregated customer wallets held with a qualified custodian, insured.",
                        "ownership": "No shareholder holds 25 percent or more; parent company Example Holding Group.",
                        "record_keeping": "Five-year record-keeping for Travel Rule and transaction data, as our regulator requires.",
                        "data_protection": "Encrypted at rest and in transit, stored in the EU."
                      }
                    }
                  ]
                }
              }
            }
          },
          "404": {
            "description": "Tidak ada entri direktori atau anggota jaringan Didit terdaftar yang memiliki id ini. Profil VASP Anda sendiri tidak pernah menjadi pihak lawan Anda.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "detail": "No directory entry or Didit network member has this id."
                }
              }
            }
          }
        }
      },
      "post": {
        "summary": "Kirim kuesioner uji tuntas ke VASP",
        "description": "Kirim kuesioner uji tuntas standar Didit melalui email ke alamat kepatuhan yang tercatat untuk pihak lawan, dengan tautan jawaban sekali pakai. Pihak lawan memiliki waktu 30 hari untuk menjawab setiap pertanyaan; jawaban tetap berlaku selama 365 hari. Pengiriman baru menggantikan kuesioner Anda sebelumnya yang belum dijawab untuk pihak lawan yang sama, yang tautannya akan berhenti berfungsi. Satu email per menit per alamat.",
        "operationId": "sendTravelRuleVaspQuestionnaire",
        "x-didit-sdk": {
          "resource": "travel_rule",
          "method": "send_vasp_questionnaire",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Travel Rule"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "vasp_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "ID dari baris GET /v3/travel-rule/vasps/: entri direktori atau anggota jaringan Didit."
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TravelRuleCounterpartyQuestionnaireRequest"
              },
              "example": {
                "sent_to": "travelrule@counterparty.example"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST https://verification.didit.me/v3/travel-rule/vasps/{vasp_id}/questionnaires/ \\\n  -H 'x-api-key: YOUR_API_KEY' -H 'Content-Type: application/json' \\\n  -d '{\"sent_to\": \"travelrule@counterparty.example\"}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.travel_rule.send_vasp_questionnaire(\n    \"11111111-2222-3333-4444-555555555555\",\n    sent_to=\"travelrule@counterparty.example\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.travelRule.sendVaspQuestionnaire(\"11111111-2222-3333-4444-555555555555\", {\n  sent_to: \"travelrule@counterparty.example\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.TravelRule.SendVASPQuestionnaire(ctx, \"11111111-2222-3333-4444-555555555555\", didit.TravelRuleCounterpartyQuestionnaireRequest{\n\tSentTo: didit.String(\"travelrule@counterparty.example\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.TravelRuleCounterpartyQuestionnaireRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.travelRule().sendVaspQuestionnaire(\"11111111-2222-3333-4444-555555555555\", TravelRuleCounterpartyQuestionnaireRequest.builder()\n        .sentTo(\"travelrule@counterparty.example\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->travelRule->sendVaspQuestionnaire('11111111-2222-3333-4444-555555555555', [\n    'sent_to' => 'travelrule@counterparty.example',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.travel_rule.send_vasp_questionnaire(\n  \"11111111-2222-3333-4444-555555555555\",\n  sent_to: \"travelrule@counterparty.example\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.TravelRule.SendVaspQuestionnaireAsync(\"11111111-2222-3333-4444-555555555555\", new TravelRuleCounterpartyQuestionnaireRequest\n{\n    SentTo = \"travelrule@counterparty.example\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "202": {
            "description": "Kuesioner telah dikirim melalui email.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TravelRuleCounterpartyQuestionnaire"
                },
                "example": {
                  "id": "3f9e8d7c-6b5a-4c3d-9e2f-1a0b9c8d7e6f",
                  "status": "SENT",
                  "form_version": "1",
                  "sent_to": "travelrule@counterparty.example",
                  "sent_at": "2026-10-14T10:00:00Z",
                  "expires_at": "2026-11-13T10:00:00Z",
                  "answered_at": null,
                  "valid_until": null,
                  "current": false,
                  "answers": {}
                }
              }
            }
          },
          "400": {
            "description": "sent_to bukan alamat email yang valid atau bukan alamat kepatuhan yang tercatat untuk pihak lawan, atau pihak lawan tidak memiliki alamat kepatuhan yang tercatat.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Not on record": {
                    "value": {
                      "sent_to": [
                        "Send the questionnaire to a compliance address on record for this counterparty."
                      ]
                    }
                  },
                  "No address": {
                    "value": {
                      "sent_to": [
                        "No compliance address is on record for this counterparty. Add a contact for it first."
                      ]
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Tidak ada entri direktori atau anggota jaringan Didit terdaftar yang memiliki id ini. Profil VASP Anda sendiri tidak pernah menjadi pihak lawan Anda.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "detail": "No directory entry or Didit network member has this id."
                }
              }
            }
          },
          "429": {
            "description": "Kuesioner telah dikirim ke alamat ini kurang dari satu menit yang lalu."
          },
          "503": {
            "description": "Email tidak dapat dikirim dan tidak ada kuesioner yang dibuat. Coba lagi sebentar lagi."
          }
        }
      }
    },
    "/v3/transactions/{transaction_id}/travel-rule/": {
      "patch": {
        "summary": "Selesaikan, batalkan, kirim ulang, atau perbarui dompet pengirim transfer Travel Rule",
        "description": "Sediakan `payment_txn_id` untuk melaporkan hash on-chain dan memindahkan transfer keluar COMPLETED ke FINISHED (pasangannya pada rail INTERNAL juga berpindah ke FINISHED), `{\"action\": \"cancel\"}` untuk membatalkan transfer non-terminal, atau `{\"action\": \"resend\"}` untuk merutekan ulang transfer keluar yang tertahan di COUNTERPARTY_VASP_NOT_FOUND, COUNTERPARTY_VASP_NOT_REACHABLE, atau NOT_ENOUGH_COUNTERPARTY_DATA (perbaiki data pihak lawan terlebih dahulu, misalnya menambahkan travel_address ke entri dompet tujuan). resend hanya berlaku untuk transfer keluar. `{\"action\": \"update_compliance_email\", \"compliance_email\": \"desk@example.com\"}` menggantikan email kepatuhan transfer keluar di salah satu dari tiga status tersebut, perbaikan untuk `reason: email_undeliverable`: status tidak berubah, dan `resend` berikutnya mengirimkan permintaan ke alamat tersebut. Pengiriman ulang dimasukkan ke antrean, tidak dijalankan di dalam permintaan: respons menampilkan transfer kembali dalam AWAITING_COUNTERPARTY dengan entri timeline `resend queued` dan `delivery` yang diantrekan, dan informasi tentang tujuan pengirimannya diterima melalui webhook `travel_rule.status.updated`. Ketika transfer dikirimkan melalui GTR, VerifyVASP, atau Sygna Bridge, jaringan mengetahui hash on-chain atau pembatalan setelah respons, dengan percobaan ulang; `delivery` menunjukkan status pesan tersebut. `{\"action\": \"update_originator_wallet\", \"wallet_address\": \"...\"}` mencatat dompet tempat dana sebenarnya keluar pada transfer keluar, misalnya alamat penarikan UTXO yang disiarkan alih-alih dompet utama yang Anda deklarasikan. Tindakan ini hanya mengubah catatan: tidak ada yang dikirim ulang ke pihak lawan dan status tetap sama. Pengirim menjadi `chain_details.originator` dengan `source: updated`, perubahan ditambahkan ke `timeline` dengan dompet sebelumnya dan dompet baru, dan pasangan transfer pada rail INTERNAL diperbarui dengan cara yang sama. `{\"action\": \"beneficiary_vasp\", \"beneficiary_vasp\": \"<directory VASP id>\"}` menentukan sendiri pihak lawan saat penemuan tidak berhasil, pada transfer keluar di COUNTERPARTY_VASP_NOT_FOUND, COUNTERPARTY_VASP_NOT_REACHABLE, atau NOT_ENOUGH_COUNTERPARTY_DATA: transfer dirutekan ke VASP tersebut dan dikirimkan kembali.",
        "operationId": "patchTravelRuleTransfer",
        "x-didit-sdk": {
          "resource": "transactions.travel_rule",
          "method": "update_transfer",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Travel Rule"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "transaction_id",
            "in": "path",
            "required": true,
            "description": "UUID transaksi yang stabil dari Didit yang memiliki transfer tersebut.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TravelRuleTransferPatchRequest"
              },
              "examples": {
                "Finish": {
                  "value": {
                    "payment_txn_id": "0xchainhash"
                  }
                },
                "Cancel": {
                  "value": {
                    "action": "cancel"
                  }
                },
                "Resend": {
                  "value": {
                    "action": "resend"
                  }
                },
                "Update compliance email": {
                  "value": {
                    "action": "update_compliance_email",
                    "compliance_email": "desk@example.com"
                  }
                },
                "Update originator wallet": {
                  "value": {
                    "action": "update_originator_wallet",
                    "wallet_address": "bc1qOriginatorInputAddress01"
                  }
                },
                "Name the counterparty": {
                  "value": {
                    "action": "beneficiary_vasp",
                    "beneficiary_vasp": "9f1c2b34-5d6e-4f70-8a91-b2c3d4e5f607"
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X PATCH https://verification.didit.me/v3/transactions/{transaction_id}/travel-rule/ \\\n  -H 'x-api-key: YOUR_API_KEY' -H 'Content-Type: application/json' \\\n  -d '{\"payment_txn_id\": \"0xchainhash\"}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.transactions.travel_rule.update_transfer(\n    \"11111111-2222-3333-4444-555555555555\",\n    payment_txn_id=\"0xchainhash\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.transactions.travelRule.updateTransfer(\"11111111-2222-3333-4444-555555555555\", {\n  payment_txn_id: \"0xchainhash\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Transactions.TravelRule.UpdateTransfer(ctx, \"11111111-2222-3333-4444-555555555555\", didit.TravelRuleTransferPatchRequest{\n\tPaymentTxnID: didit.String(\"0xchainhash\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.TravelRuleTransferPatchRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.transactions().travelRule().updateTransfer(\"11111111-2222-3333-4444-555555555555\", TravelRuleTransferPatchRequest.builder()\n        .paymentTxnId(\"0xchainhash\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->transactions->travelRule->updateTransfer('11111111-2222-3333-4444-555555555555', [\n    'payment_txn_id' => '0xchainhash',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.transactions.travel_rule.update_transfer(\n  \"11111111-2222-3333-4444-555555555555\",\n  payment_txn_id: \"0xchainhash\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Transactions.TravelRule.UpdateTransferAsync(\"11111111-2222-3333-4444-555555555555\", new TravelRuleTransferPatchRequest\n{\n    PaymentTxnId = \"0xchainhash\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "Transfer yang diperbarui. Setelah `update_compliance_email`, statusnya tidak berubah dan mempertahankan `reason: email_undeliverable` hingga `resend` berikutnya.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TravelRuleTransferDetail"
                }
              }
            }
          },
          "400": {
            "description": "Baik payment_txn_id maupun tindakan yang didukung tidak diberikan, `compliance_email` tidak ada atau bukan alamat email pada `update_compliance_email`, atau, untuk `update_originator_wallet`, tidak ada wallet_address, dompet atau memo yang tidak dapat dibawa oleh blockchain transfer, atau dompet yang bukan merupakan salah satu input UTXO transfer, atau `beneficiary_vasp` tidak ada atau bukan ID VASP direktori yang valid.",
            "content": {
              "application/json": {
                "examples": {
                  "No action": {
                    "value": {
                      "detail": [
                        "Provide payment_txn_id, action=cancel, action=resend, action=beneficiary_vasp, action=update_originator_wallet or action=update_compliance_email."
                      ]
                    }
                  },
                  "Invalid compliance email": {
                    "value": {
                      "compliance_email": [
                        "Enter a valid email address."
                      ]
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Transaksi tidak dikenal, transaksi tidak memiliki transfer Travel Rule, atau (tindakan `beneficiary_vasp`) tidak ada entri direktori yang memiliki id tersebut."
          },
          "409": {
            "description": "Transfer tidak berada dalam status yang memungkinkan operasi ini (misalnya tidak COMPLETED/outbound untuk penyelesaian, sudah terminal untuk pembatalan, atau bukan transfer keluar dalam status yang dapat dikirim ulang untuk pengiriman ulang). `update_compliance_email` mengembalikan `409` untuk transfer masuk, dan untuk transfer keluar di luar COUNTERPARTY_VASP_NOT_FOUND, COUNTERPARTY_VASP_NOT_REACHABLE, dan NOT_ENOUGH_COUNTERPARTY_DATA. `update_originator_wallet` mengembalikan `409` untuk transfer masuk, dibatalkan, atau kedaluwarsa. `beneficiary_vasp` mengembalikan `409` kecuali transfer berstatus keluar dan berada dalam COUNTERPARTY_VASP_NOT_FOUND, COUNTERPARTY_VASP_NOT_REACHABLE, atau NOT_ENOUGH_COUNTERPARTY_DATA.",
            "content": {
              "application/json": {
                "examples": {
                  "Cancel from a terminal status": {
                    "value": {
                      "detail": "Transfer is already in a terminal state."
                    }
                  },
                  "Resend not allowed": {
                    "value": {
                      "detail": "Transfer cannot be resent from its current state."
                    }
                  },
                  "Finish not allowed": {
                    "value": {
                      "detail": "Transfer must be an outbound transfer in COMPLETED status to finish."
                    }
                  },
                  "Compliance email cannot change": {
                    "value": {
                      "detail": "The compliance email of this transfer cannot change from its current state."
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v3/transactions/{transaction_id}/travel-rule/ownership/": {
      "post": {
        "summary": "Konfirmasi atau tolak kepemilikan dompet",
        "description": "Selesaikan transfer yang menunggu kepemilikan dompet: panggil ini pada sisi transfer Anda sendiri saat statusnya UNCONFIRMED_OWNERSHIP, atau saat statusnya adalah transfer masuk dalam ON_HOLD. Mengonfirmasi akan menandai entri buku alamat dompet yang cocok sebagai terverifikasi kepemilikannya (untuk transfer masuk ON_HOLD tanpa entri, Didit membuat entri dari beneficiary_data.wallet_address) dan menjalankan pencocokan nama penerima di kedua sisi transfer; menolak akan menolak kedua sisi. Transfer masuk yang depositnya telah selesai akan berpindah ke FINISHED saat pencocokan berhasil. Ketika dompet pihak lawan dinyatakan sebagai dompet swakelola (counterparty.payment_method.method_type: unhosted_wallet), mengonfirmasi akan mencatat bahwa pelanggan memverifikasi siapa yang mengontrol dompet tersebut dan menyelesaikan transfer (COMPLETED) di kedua arah, atau FINISHED untuk deposit masuk yang hash on-chain-nya sudah diketahui. Dompet yang diverifikasi adalah milik pihak lawan: tujuan penarikan keluar, atau sumber (dompet pengirim) deposit masuk. Jika belum ada di buku alamat dompet Anda, Didit menambahkannya sebagai terverifikasi kepemilikannya di bawah nama pihak lawan; jika buku alamat telah menyimpannya dengan nama pemegang yang berbeda, transfer akan berpindah ke COUNTERPARTY_MISMATCHED_DATA. Untuk transfer TRP masuk dalam status UNCONFIRMED_OWNERSHIP, ON_HOLD, atau COUNTERPARTY_MISMATCHED_DATA, Didit mengirimkan keputusan Anda ke VASP pengirim: menyetujui akan mengembalikan alamat pembayaran (wallet_address, atau alamat entri yang cocok) dan memindahkan transfer ke COMPLETED, dan menolak akan menolaknya. Panggilan yang sama juga memutuskan transfer masuk yang dikirim oleh pihak lawan GTR atau Sygna Bridge dan menunggu peninjauan Anda (`UNCONFIRMED_OWNERSHIP`, `ON_HOLD`, atau `COUNTERPARTY_MISMATCHED_DATA`): `confirmed: true` menyetujuinya (sampaikan `wallet_address` ketika transfer tidak mencantumkan alamat dompet) dan `confirmed: false` menolaknya, dan jawaban akan dikirimkan ke jaringan setelah respons diberikan, dengan coba lagi. VerifyVASP mengambil jawabannya saat bertanya, sehingga transfer VerifyVASP yang memerlukan peninjauan Anda akan langsung ditolak dan tidak dapat diputuskan nanti.",
        "operationId": "confirmTravelRuleOwnership",
        "x-didit-sdk": {
          "resource": "transactions.travel_rule",
          "method": "confirm_ownership",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Travel Rule"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "transaction_id",
            "in": "path",
            "required": true,
            "description": "UUID stabil dari Didit untuk transaksi yang disimpan aplikasi Anda untuk transfer ini: transaksi sisi penerima pada transfer jalur INTERNAL, atau transaksi yang Anda buat (keluar atau masuk) ketika dompet pihak lawan dinyatakan swakelola.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TravelRuleOwnershipConfirmRequest"
              },
              "example": {
                "confirmed": true
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST https://verification.didit.me/v3/transactions/{transaction_id}/travel-rule/ownership/ \\\n  -H 'x-api-key: YOUR_API_KEY' -H 'Content-Type: application/json' \\\n  -d '{\"confirmed\": true}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.transactions.travel_rule.confirm_ownership(\n    \"11111111-2222-3333-4444-555555555555\",\n    confirmed=True,\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.transactions.travelRule.confirmOwnership(\"11111111-2222-3333-4444-555555555555\", {\n  confirmed: true,\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Transactions.TravelRule.ConfirmOwnership(ctx, \"11111111-2222-3333-4444-555555555555\", didit.TravelRuleOwnershipConfirmRequest{\n\tConfirmed: true,\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.TravelRuleOwnershipConfirmRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.transactions().travelRule().confirmOwnership(\"11111111-2222-3333-4444-555555555555\", TravelRuleOwnershipConfirmRequest.builder()\n        .confirmed(true)\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->transactions->travelRule->confirmOwnership('11111111-2222-3333-4444-555555555555', [\n    'confirmed' => true,\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.transactions.travel_rule.confirm_ownership(\n  \"11111111-2222-3333-4444-555555555555\",\n  confirmed: true\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Transactions.TravelRule.ConfirmOwnershipAsync(\"11111111-2222-3333-4444-555555555555\", new TravelRuleOwnershipConfirmRequest\n{\n    Confirmed = true,\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "Transfer yang diperbarui. Untuk transfer masuk, originator_data/beneficiary_data milik pihak lawan tetap disamarkan (`data_masked: true`) hingga kepemilikan dikonfirmasi, kemudian `data_unmasked` mencatat kapan, mengapa, dan oleh siapa.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TravelRuleTransferDetail"
                }
              }
            }
          },
          "409": {
            "description": "Transfer tidak sedang menunggu konfirmasi kepemilikan, tidak ada entri buku alamat dompet yang cocok dengan dompet pihak lawan, transfer INTERNAL dari pelanggan Didit lain memerlukan bukti kontrol (pesan bertanda tangan atau deposit uji) sebelum dapat dikonfirmasi, atau transfer jaringan sudah dijawab melalui jaringannya (transfer VerifyVASP, atau transfer GTR atau Sygna Bridge yang sudah Anda atau Didit putuskan).",
            "content": {
              "application/json": {
                "examples": {
                  "Not awaiting confirmation": {
                    "value": {
                      "detail": "Transfer is not awaiting ownership confirmation."
                    }
                  },
                  "No matching address book entry": {
                    "value": {
                      "detail": "wallet address entry no longer available"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Kesalahan validasi: confirmed tidak ada, persetujuan TRP masuk tidak memiliki wallet_address dan tidak ada alamat cadangan, atau `confirmed: true` pada transfer dompet swakelola yang dideklarasikan yang tidak menyebutkan dompet pihak lawan dan tidak ada `wallet_address` yang dikirimkan.",
            "content": {
              "application/json": {
                "examples": {
                  "No payment address": {
                    "value": {
                      "wallet_address": [
                        "wallet_address is required to approve."
                      ]
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Transaksi tidak dikenal, atau transaksi tidak memiliki transfer Travel Rule."
          },
          "502": {
            "description": "Hanya transfer TRP masuk: Didit tidak dapat mengirimkan keputusan Anda ke VASP pengirim, sehingga status transfer tidak berubah.",
            "content": {
              "application/json": {
                "examples": {
                  "Callback not delivered": {
                    "value": {
                      "detail": "Counterparty inquiry-resolution callback could not be delivered."
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v3/transactions/{transaction_id}/travel-rule/messages/": {
      "get": {
        "summary": "Daftar pesan Travel Rule",
        "description": "Pesan dan permintaan dokumen yang dipertukarkan dengan VASP pihak lawan mengenai transfer ini.",
        "operationId": "listTravelRuleMessages",
        "x-didit-sdk": {
          "resource": "transactions.travel_rule",
          "method": "list_messages",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Travel Rule"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "transaction_id",
            "in": "path",
            "required": true,
            "description": "UUID transaksi yang stabil dari Didit yang memiliki transfer tersebut.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET https://verification.didit.me/v3/transactions/{transaction_id}/travel-rule/messages/ \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.transactions.travel_rule.list_messages(\n    \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.transactions.travelRule.listMessages(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Transactions.TravelRule.ListMessages(ctx, \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.transactions().travelRule().listMessages(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->transactions->travelRule->listMessages('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.transactions.travel_rule.list_messages(\"11111111-2222-3333-4444-555555555555\").each do |item|\n  puts item.to_h\nend"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Transactions.TravelRule.ListMessagesAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "Pesan, terlama lebih dahulu.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/TravelRuleMessage"
                  }
                }
              }
            }
          },
          "404": {
            "description": "Transaksi atau token tidak dikenal, atau tidak ada transfer Travel Rule pada transaksi tersebut."
          }
        }
      },
      "post": {
        "summary": "Kirim pesan Travel Rule atau permintaan dokumen",
        "description": "Mengirim pesan atau permintaan dokumen ke VASP pihak lawan. Berfungsi pada transfer INTERNAL (pelanggan Didit lainnya melihatnya di sisi pasangannya) dan transfer EMAIL (pihak lawan menerima email dan menjawab di portal pengambilan). Transfer melalui TRP, GTR, TRUST, VerifyVASP, atau Sygna tidak membawa pesan, karena protokol tersebut tidak memilikinya. Batas: 100 pesan per transfer, 5000 karakter per isi pesan, 10 dokumen yang diminta, 5 file masing-masing 10 MB.",
        "operationId": "createTravelRuleMessage",
        "x-didit-sdk": {
          "resource": "transactions.travel_rule",
          "method": "create_message",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Travel Rule"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "transaction_id",
            "in": "path",
            "required": true,
            "description": "UUID transaksi yang stabil dari Didit yang memiliki transfer tersebut.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TravelRuleMessageCreateRequest"
              },
              "example": {
                "kind": "DOCUMENT_REQUEST",
                "body": "Please confirm the date of birth of the beneficiary.",
                "requested_documents": [
                  "Proof of address"
                ]
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/TravelRuleMessageCreateRequest"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST https://verification.didit.me/v3/transactions/{transaction_id}/travel-rule/messages/ \\\n  -H 'x-api-key: YOUR_API_KEY' -H 'Content-Type: application/json' \\\n  -d '{\"kind\": \"DOCUMENT_REQUEST\", \"body\": \"Please confirm the date of birth of the beneficiary.\", \"requested_documents\": [\"Proof of address\"]}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.transactions.travel_rule.create_message(\n    \"11111111-2222-3333-4444-555555555555\",\n    kind=\"DOCUMENT_REQUEST\",\n    body=\"Please confirm the date of birth of the beneficiary.\",\n    requested_documents=[\"Proof of address\"],\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.transactions.travelRule.createMessage(\"11111111-2222-3333-4444-555555555555\", {\n  kind: \"DOCUMENT_REQUEST\",\n  body: \"Please confirm the date of birth of the beneficiary.\",\n  requested_documents: [\"Proof of address\"],\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Transactions.TravelRule.CreateMessage(ctx, \"11111111-2222-3333-4444-555555555555\", didit.TravelRuleMessageCreateRequest{\n\tKind:               didit.Some(didit.TravelRuleMessageCreateRequestKind(\"DOCUMENT_REQUEST\")),\n\tBody:               didit.String(\"Please confirm the date of birth of the beneficiary.\"),\n\tRequestedDocuments: didit.Some([]string{\"Proof of address\"}),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.List;\nimport me.didit.Didit;\nimport me.didit.types.TravelRuleMessageCreateRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.transactions().travelRule().createMessage(\"11111111-2222-3333-4444-555555555555\", TravelRuleMessageCreateRequest.builder()\n        .kind(TravelRuleMessageCreateRequest.Kind.of(\"DOCUMENT_REQUEST\"))\n        .body(\"Please confirm the date of birth of the beneficiary.\")\n        .requestedDocuments(List.of(\"Proof of address\"))\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->transactions->travelRule->createMessage('11111111-2222-3333-4444-555555555555', [\n    'kind' => 'DOCUMENT_REQUEST',\n    'body' => 'Please confirm the date of birth of the beneficiary.',\n    'requested_documents' => ['Proof of address'],\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.transactions.travel_rule.create_message(\n  \"11111111-2222-3333-4444-555555555555\",\n  kind: \"DOCUMENT_REQUEST\",\n  body: \"Please confirm the date of birth of the beneficiary.\",\n  requested_documents: [\"Proof of address\"]\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Transactions.TravelRule.CreateMessageAsync(\"11111111-2222-3333-4444-555555555555\", new TravelRuleMessageCreateRequest\n{\n    Kind = new TravelRuleMessageCreateRequestKind(\"DOCUMENT_REQUEST\"),\n    Body = \"Please confirm the date of birth of the beneficiary.\",\n    RequestedDocuments = new string[] { \"Proof of address\" },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "201": {
            "description": "Pesan yang tersimpan.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TravelRuleMessage"
                }
              }
            }
          },
          "400": {
            "description": "Body tidak valid, tipe atau ukuran file yang tidak diterima, lebih dari 100 pesan pada transfer, atau `reply_to` yang bukan merupakan pesan dari transfer ini.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "requested_documents": [
                    "Name at least one document the counterparty should send."
                  ]
                }
              }
            }
          },
          "404": {
            "description": "Transaksi atau token tidak dikenal, atau tidak ada transfer Travel Rule pada transaksi tersebut."
          },
          "409": {
            "description": "Tidak ada pesan yang dapat mencapai pihak lawan. `detail` memberikan alasannya: transfer berjalan melalui rel jaringan (TRP, GTR, TRUST, VerifyVASP, atau Sygna), transfer belum memiliki pihak lawan, data transfer INTERNAL tidak cocok dengan pemegang dompet sehingga tidak ada yang sampai ke penerima, atau tautan pengambilan transfer EMAIL telah kedaluwarsa atau transfer ditutup.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v3/travel-rule/pickup/{token}/": {
      "get": {
        "summary": "Dapatkan info penjemputan jalur email",
        "description": "Publik, tidak terautentikasi. Memungkinkan VASP pihak lawan non-Didit melihat pratinjau pertukaran yang tertunda dari tautan pengambilan yang dikirim melalui email. Token itu sendiri berfungsi sebagai autentikasi.",
        "operationId": "getTravelRulePickup",
        "x-didit-sdk": {
          "resource": "travel_rule",
          "method": "retrieve_pickup",
          "auth": "public",
          "server": false
        },
        "tags": [
          "Travel Rule"
        ],
        "security": [
          {}
        ],
        "parameters": [
          {
            "name": "token",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "contact",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Nilai `?contact=` dari tautan, kontak tujuan pengiriman tautan. Dikembalikan sebagai `contact` tanpa perubahan; nilai ini tidak divalidasi."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl https://verification.didit.me/v3/travel-rule/pickup/{token}/"
          }
        ],
        "responses": {
          "200": {
            "description": "Pratinjau pengambilan.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TravelRulePickupInfo"
                },
                "example": {
                  "reference": "33333333-4444-5555-6666-777777777777",
                  "requested_at": "2026-07-05T10:00:00Z",
                  "originator_vasp_name": "Origin CASP SL",
                  "originator_vasp_lei": "529900EXAMPLEORIG001",
                  "recipient_vasp_name": "Example Counterparty VASP",
                  "language": "es",
                  "amount": "0.250000000000000000",
                  "currency": "ETH",
                  "fiat_amount": "",
                  "fiat_currency": "",
                  "chain": "ETH",
                  "beneficiary_wallet": "0xede2d7e4f5b097e6391ab6bbcf2f47a53f4778cb",
                  "status": "AWAITING_COUNTERPARTY",
                  "ivms_version": "ivms101.2023",
                  "deadline_at": "2026-07-07T10:00:00Z",
                  "reminders_sent": 0,
                  "contact": "",
                  "decline_reasons": [
                    "data_mismatch",
                    "not_our_customer",
                    "wallet_not_hosted",
                    "sanctions",
                    "risk_appetite",
                    "jurisdiction",
                    "insufficient_data",
                    "other"
                  ],
                  "join_invitation": {
                    "eligible": false,
                    "url": ""
                  },
                  "originator_data": {
                    "name": "Jane Doe",
                    "wallet_address": "0x77ccff0cc624a53cd8b8d8703ced826710211ec7"
                  },
                  "beneficiary_data": {
                    "name": "Ana Diaz",
                    "wallet_address": "0xede2d7e4f5b097e6391ab6bbcf2f47a53f4778cb"
                  },
                  "ivms_request": {
                    "originator": {
                      "originatorPersons": [
                        {
                          "naturalPerson": {
                            "name": {
                              "nameIdentifier": [
                                {
                                  "primaryIdentifier": "Doe",
                                  "secondaryIdentifier": "Jane",
                                  "nameIdentifierType": "LEGL"
                                }
                              ]
                            }
                          }
                        }
                      ],
                      "accountNumber": [
                        "0x77ccff0cc624a53cd8b8d8703ced826710211ec7"
                      ]
                    },
                    "beneficiary": {
                      "beneficiaryPersons": [
                        {
                          "naturalPerson": {
                            "name": {
                              "nameIdentifier": [
                                {
                                  "primaryIdentifier": "Diaz",
                                  "secondaryIdentifier": "Ana",
                                  "nameIdentifierType": "LEGL"
                                }
                              ]
                            }
                          }
                        }
                      ],
                      "accountNumber": [
                        "0xede2d7e4f5b097e6391ab6bbcf2f47a53f4778cb"
                      ]
                    }
                  },
                  "data_masked": false
                }
              }
            }
          },
          "404": {
            "description": "Token tidak dikenal."
          },
          "410": {
            "description": "Jendela waktu telah ditutup: pihak lawan telah menjawab, transfer keluar dari AWAITING_COUNTERPARTY, atau batas waktu telah terlewati."
          }
        }
      }
    },
    "/v3/travel-rule/pickup/{token}/respond/": {
      "post": {
        "summary": "Merespons pengambilan melalui jalur email",
        "description": "Publik, tanpa autentikasi. Menerima atau menolak pertukaran dari tautan pengambilan yang dikirim melalui email. Saat diterima, beneficiary_name diperiksa terhadap kebijakan name_matching_strictness pengirim.",
        "operationId": "respondTravelRulePickup",
        "x-didit-sdk": {
          "resource": "travel_rule",
          "method": "respond_pickup",
          "auth": "public",
          "server": false
        },
        "tags": [
          "Travel Rule"
        ],
        "security": [
          {}
        ],
        "parameters": [
          {
            "name": "token",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "contact",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Nilai `?contact=` dari tautan. Digunakan saat isi permintaan tidak mengirimkan `contact`."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TravelRulePickupRespondRequest"
              },
              "example": {
                "decision": "accept",
                "beneficiary_name": "Carlos Ruiz"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST https://verification.didit.me/v3/travel-rule/pickup/{token}/respond/ \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"decision\": \"accept\", \"beneficiary_name\": \"Carlos Ruiz\"}'"
          }
        ],
        "responses": {
          "200": {
            "description": "Status pertukaran yang dihasilkan: COMPLETED atau COUNTERPARTY_MISMATCHED_DATA setelah persetujuan, COUNTERPARTY_VASP_GENERAL_DECLINE setelah penolakan, yang juga menggemakan `decline_reason`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string"
                    },
                    "decline_reason": {
                      "type": "string",
                      "description": "Hadir setelah penolakan."
                    }
                  }
                },
                "examples": {
                  "accepted": {
                    "value": {
                      "status": "COMPLETED"
                    }
                  },
                  "declined": {
                    "value": {
                      "status": "COUNTERPARTY_VASP_GENERAL_DECLINE",
                      "decline_reason": "not_our_customer"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Kolom tidak valid: contohnya `decision` tidak ada atau bukan `accept` atau `decline`, `decline_detail` tidak ada pada penolakan dengan `decline_reason: other`, `ivms_response` yang bukan merupakan objek IVMS 101 atau lebih panjang dari 16384 karakter, atau `contact` di dalam body yang bukan merupakan UUID (`{\"contact\": [\"Must be a valid UUID.\"]}`).",
            "content": {
              "application/json": {
                "example": {
                  "decline_detail": [
                    "Say what the reason is when you choose another reason."
                  ]
                }
              }
            }
          },
          "404": {
            "description": "Token tidak dikenal."
          },
          "410": {
            "description": "Jendela waktu telah ditutup: pihak lawan telah menjawab, transfer keluar dari AWAITING_COUNTERPARTY, atau batas waktu telah terlewati."
          }
        }
      }
    },
    "/v3/travel-rule/pickup/{token}/messages/": {
      "get": {
        "summary": "Mencantumkan pesan pengambilan",
        "description": "Publik, tidak terautentikasi. Pesan transfer rail-EMAIL sebagaimana dibaca oleh VASP pihak lawan: apa yang dikirimkan pelanggan berstatus `INBOUND` dan ditandatangani dengan nama VASP pelanggan. Token berfungsi sebagai autentikasi.",
        "operationId": "listTravelRulePickupMessages",
        "x-didit-sdk": {
          "resource": "travel_rule",
          "method": "list_pickup_messages",
          "auth": "public",
          "server": false
        },
        "tags": [
          "Travel Rule"
        ],
        "security": [
          {}
        ],
        "parameters": [
          {
            "name": "token",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl https://verification.didit.me/v3/travel-rule/pickup/{token}/messages/"
          }
        ],
        "responses": {
          "200": {
            "description": "Pesan, terlama lebih dahulu, dari sisi pihak lawan.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/TravelRuleMessage"
                  }
                }
              }
            }
          },
          "404": {
            "description": "Token tidak dikenal."
          },
          "410": {
            "description": "Tautan penjemputan telah kedaluwarsa atau transfer telah ditutup."
          }
        }
      },
      "post": {
        "summary": "Balas di portal penjemputan",
        "description": "Publik, tidak terautentikasi. VASP pihak lawan membalas pada transfer rail-EMAIL. Payload isi sama dengan pesan transaksi; lampiran harus berupa PDF, PNG, JPEG, atau WebP. Token berfungsi sebagai autentikasi.",
        "operationId": "createTravelRulePickupMessage",
        "x-didit-sdk": {
          "resource": "travel_rule",
          "method": "create_pickup_message",
          "auth": "public",
          "server": false
        },
        "tags": [
          "Travel Rule"
        ],
        "security": [
          {}
        ],
        "parameters": [
          {
            "name": "token",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TravelRuleMessageCreateRequest"
              },
              "example": {
                "kind": "MESSAGE",
                "body": "Attached is the proof of address of the wallet holder."
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/TravelRuleMessageCreateRequest"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST https://verification.didit.me/v3/travel-rule/pickup/{token}/messages/ \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"kind\": \"MESSAGE\", \"body\": \"Attached is the proof of address of the wallet holder.\"}'"
          }
        ],
        "responses": {
          "201": {
            "description": "Pesan yang tersimpan.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TravelRuleMessage"
                }
              }
            }
          },
          "400": {
            "description": "Body tidak valid, tipe atau ukuran file yang tidak diterima, lebih dari 100 pesan pada transfer, atau `reply_to` yang bukan merupakan pesan dari transfer ini.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "requested_documents": [
                    "Name at least one document the counterparty should send."
                  ]
                }
              }
            }
          },
          "404": {
            "description": "Token tidak dikenal."
          },
          "410": {
            "description": "Tautan penjemputan telah kedaluwarsa atau transfer telah ditutup."
          }
        }
      }
    },
    "/v3/travel-rule/inbound/": {
      "post": {
        "summary": "Daftarkan transfer masuk pasca-deposit (sunrise)",
        "description": "Daftarkan data Travel Rule untuk deposit kripto yang telah diselesaikan on-chain sebelum pertukaran apa pun berlangsung. Membuat transaksi travelRule masuk (atau menggunakan kembali deposit yang belum diklaim) dan mencocokkan transfer dengan buku alamat dompet Anda. Untuk transaksi yang baru dibuat, Didit mengirimkan transaction.created terlebih dahulu dan webhook travel_rule.status.updated setelahnya.",
        "operationId": "registerTravelRuleInbound",
        "x-didit-sdk": {
          "resource": "travel_rule",
          "method": "register_inbound",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Travel Rule"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TravelRuleInboundRequest"
              },
              "example": {
                "chain": "ETH",
                "txid": "0xdeposit-hash",
                "wallet_address": "0xYourDepositWallet",
                "amount": "500.00",
                "currency": "USDC",
                "originator_data": {
                  "name": "Origin CASP SL"
                },
                "beneficiary_data": {
                  "name": "Ana Diaz"
                },
                "originating_vasp": {
                  "name": "Origin CASP SL",
                  "lei": "",
                  "travel_address": "ta9JbXbsBSuS5ozArJRFVgvBHMVnDGUnrPPChSZYQsuZTn3kPrJXUQ7RSLUEJ5KjyPvr8C9sAxmPtZfGsQVKCi4n8ShxP9BkbDdbtjtA9aumNybAZ1BxC"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST https://verification.didit.me/v3/travel-rule/inbound/ \\\n  -H 'x-api-key: YOUR_API_KEY' -H 'Content-Type: application/json' \\\n  -d '{\"chain\":\"ETH\",\"txid\":\"0xdeposit-hash\",\"wallet_address\":\"0xYourDepositWallet\",\"amount\":\"500.00\",\"currency\":\"USDC\"}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.travel_rule.register_inbound(\n    chain=\"ETH\",\n    txid=\"0xdeposit-hash\",\n    wallet_address=\"0xYourDepositWallet\",\n    amount=\"500.00\",\n    currency=\"USDC\",\n    originator_data={\"name\": \"Origin CASP SL\"},\n    beneficiary_data={\"name\": \"Ana Diaz\"},\n    originating_vasp={\n        \"name\": \"Origin CASP SL\",\n        \"lei\": \"\",\n        \"travel_address\": \"ta9JbXbsBSuS5ozArJRFVgvBHMVnDGUnrPPChSZYQsuZTn3kPrJXUQ7RSLUEJ5KjyPvr8C9sAxmPtZfGsQVKCi4n8ShxP9BkbDdbtjtA9aumNybAZ1BxC\",\n    },\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.travelRule.registerInbound({\n  chain: \"ETH\",\n  txid: \"0xdeposit-hash\",\n  wallet_address: \"0xYourDepositWallet\",\n  amount: \"500.00\",\n  currency: \"USDC\",\n  originator_data: { name: \"Origin CASP SL\" },\n  beneficiary_data: { name: \"Ana Diaz\" },\n  originating_vasp: {\n    name: \"Origin CASP SL\",\n    lei: \"\",\n    travel_address: \"ta9JbXbsBSuS5ozArJRFVgvBHMVnDGUnrPPChSZYQsuZTn3kPrJXUQ7RSLUEJ5KjyPvr8C9sAxmPtZfGsQVKCi4n8ShxP9BkbDdbtjtA9aumNybAZ1BxC\",\n  },\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.TravelRule.RegisterInbound(ctx, didit.TravelRuleInboundRequest{\n\tChain:           \"ETH\",\n\tTxid:            \"0xdeposit-hash\",\n\tWalletAddress:   \"0xYourDepositWallet\",\n\tAmount:          \"500.00\",\n\tCurrency:        \"USDC\",\n\tOriginatorData:  didit.Some(map[string]any{\"name\": \"Origin CASP SL\"}),\n\tBeneficiaryData: didit.Some(map[string]any{\"name\": \"Ana Diaz\"}),\n\tOriginatingVASP: didit.Some(didit.TravelRuleInboundRequestOriginatingVASP{\n\t\tName:          didit.String(\"Origin CASP SL\"),\n\t\tLei:           didit.String(\"\"),\n\t\tTravelAddress: didit.String(\"ta9JbXbsBSuS5ozArJRFVgvBHMVnDGUnrPPChSZYQsuZTn3kPrJXUQ7RSLUEJ5KjyPvr8C9sAxmPtZfGsQVKCi4n8ShxP9BkbDdbtjtA9aumNybAZ1BxC\"),\n\t}),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.TravelRuleInboundRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.travelRule().registerInbound(TravelRuleInboundRequest.builder()\n        .chain(\"ETH\")\n        .txid(\"0xdeposit-hash\")\n        .walletAddress(\"0xYourDepositWallet\")\n        .amount(\"500.00\")\n        .currency(\"USDC\")\n        .originatorData(Map.of(\"name\", \"Origin CASP SL\"))\n        .beneficiaryData(Map.of(\"name\", \"Ana Diaz\"))\n        .originatingVasp(TravelRuleInboundRequest.OriginatingVasp.builder()\n                .name(\"Origin CASP SL\")\n                .lei(\"\")\n                .travelAddress(\"ta9JbXbsBSuS5ozArJRFVgvBHMVnDGUnrPPChSZYQsuZTn3kPrJXUQ7RSLUEJ5KjyPvr8C9sAxmPtZfGsQVKCi4n8ShxP9BkbDdbtjtA9aumNybAZ1BxC\")\n                .build())\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->travelRule->registerInbound([\n    'chain' => 'ETH',\n    'txid' => '0xdeposit-hash',\n    'wallet_address' => '0xYourDepositWallet',\n    'amount' => '500.00',\n    'currency' => 'USDC',\n    'originator_data' => ['name' => 'Origin CASP SL'],\n    'beneficiary_data' => ['name' => 'Ana Diaz'],\n    'originating_vasp' => [\n        'name' => 'Origin CASP SL',\n        'lei' => '',\n        'travel_address' => 'ta9JbXbsBSuS5ozArJRFVgvBHMVnDGUnrPPChSZYQsuZTn3kPrJXUQ7RSLUEJ5KjyPvr8C9sAxmPtZfGsQVKCi4n8ShxP9BkbDdbtjtA9aumNybAZ1BxC',\n    ],\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.travel_rule.register_inbound(\n  chain: \"ETH\",\n  txid: \"0xdeposit-hash\",\n  wallet_address: \"0xYourDepositWallet\",\n  amount: \"500.00\",\n  currency: \"USDC\",\n  originator_data: { name: \"Origin CASP SL\" },\n  beneficiary_data: { name: \"Ana Diaz\" },\n  originating_vasp: {\n    name: \"Origin CASP SL\",\n    lei: \"\",\n    travel_address: \"ta9JbXbsBSuS5ozArJRFVgvBHMVnDGUnrPPChSZYQsuZTn3kPrJXUQ7RSLUEJ5KjyPvr8C9sAxmPtZfGsQVKCi4n8ShxP9BkbDdbtjtA9aumNybAZ1BxC\",\n  }\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.TravelRule.RegisterInboundAsync(new TravelRuleInboundRequest\n{\n    Chain = \"ETH\",\n    Txid = \"0xdeposit-hash\",\n    WalletAddress = \"0xYourDepositWallet\",\n    Amount = \"500.00\",\n    Currency = \"USDC\",\n    OriginatorData = new Dictionary<string, object> { [\"name\"] = \"Origin CASP SL\" },\n    BeneficiaryData = new Dictionary<string, object> { [\"name\"] = \"Ana Diaz\" },\n    OriginatingVasp = new TravelRuleInboundRequestOriginatingVasp\n    {\n        Name = \"Origin CASP SL\",\n        Lei = \"\",\n        TravelAddress = \"ta9JbXbsBSuS5ozArJRFVgvBHMVnDGUnrPPChSZYQsuZTn3kPrJXUQ7RSLUEJ5KjyPvr8C9sAxmPtZfGsQVKCi4n8ShxP9BkbDdbtjtA9aumNybAZ1BxC\",\n    },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "Transfer untuk txid dan wallet_address ini sudah terdaftar; transfer yang ada dikembalikan tanpa perubahan (created bernilai false).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TravelRuleInboundResponse"
                }
              }
            }
          },
          "201": {
            "description": "Transfer Travel Rule baru telah didaftarkan, pada transaksi masuk baru atau pada deposit belum diklaim yang sudah ada (created bernilai true).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TravelRuleInboundResponse"
                }
              }
            }
          },
          "400": {
            "description": "Kolom wajib (`chain`, `txid`, `wallet_address`, `amount`, `currency`) tidak ada, `originating_vasp.lei` bukan LEI yang valid, `originating_vasp.travel_address` bukan Travel Address yang valid, memo, X-address, atau `utxo` yang tidak dapat dibawa oleh chain, atau `originator_data` / `beneficiary_data` yang bukan merupakan objek.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing field": {
                    "value": {
                      "txid": [
                        "This field is required."
                      ]
                    }
                  },
                  "Invalid LEI": {
                    "value": {
                      "originating_vasp": {
                        "lei": [
                          "Invalid LEI: expected 20 alphanumeric characters (ISO 17442)."
                        ]
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v3/travel-rule/test-vasp/inbound/": {
      "post": {
        "summary": "Picu transfer masuk dari VASP Pengujian Didit (sandbox)",
        "description": "Khusus aplikasi sandbox. Test VASP Didit mengirimkan transfer Travel Rule masuk ke aplikasi Anda, sehingga Anda dapat menguji sisi penerimaan dari bursa secara menyeluruh sebelum masuk ke lingkungan produksi. Transfer dibukukan dan diputuskan dengan logika yang sama yang dijalankan transfer masuk nyata dari jaringan terhadap buku alamat dompet Anda, sehingga kotak masuk, keputusan, dan alur kepemilikan dompet berperilaku persis seperti di lingkungan produksi. Tidak ada yang keluar dari Didit. Aplikasi di lingkungan produksi menerima 400. Kirimkan `reference` yang sama lagi untuk mendapatkan transfer yang dibukukan pada panggilan pertama, alih-alih membuat transfer kedua.",
        "operationId": "triggerTravelRuleTestVaspInbound",
        "x-didit-sdk": {
          "resource": "transactions.travel_rule",
          "method": "trigger_test_vasp_inbound",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Travel Rule"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TravelRuleTestVaspInboundRequest"
              },
              "example": {
                "beneficiary_wallet_address": "0xYourSandboxWallet",
                "scenario": "accept",
                "amount": "1",
                "reference": "demo-001"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST https://verification.didit.me/v3/travel-rule/test-vasp/inbound/ \\\n  -H 'x-api-key: YOUR_SANDBOX_API_KEY' -H 'Content-Type: application/json' \\\n  -d '{\"beneficiary_wallet_address\":\"0xYourSandboxWallet\",\"scenario\":\"accept\",\"reference\":\"demo-001\"}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.transactions.travel_rule.trigger_test_vasp_inbound(\n    beneficiary_wallet_address=\"0xYourSandboxWallet\",\n    scenario=\"accept\",\n    amount=\"1\",\n    reference=\"demo-001\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.transactions.travelRule.triggerTestVaspInbound({\n  beneficiary_wallet_address: \"0xYourSandboxWallet\",\n  scenario: \"accept\",\n  amount: \"1\",\n  reference: \"demo-001\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Transactions.TravelRule.TriggerTestVASPInbound(ctx, didit.TravelRuleTestVASPInboundRequest{\n\tBeneficiaryWalletAddress: \"0xYourSandboxWallet\",\n\tScenario:                 didit.Some(didit.TravelRuleTestVASPInboundRequestScenario(\"accept\")),\n\tAmount:                   didit.String(\"1\"),\n\tReference:                didit.String(\"demo-001\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.TravelRuleTestVaspInboundRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.transactions().travelRule().triggerTestVaspInbound(TravelRuleTestVaspInboundRequest.builder()\n        .beneficiaryWalletAddress(\"0xYourSandboxWallet\")\n        .scenario(TravelRuleTestVaspInboundRequest.Scenario.of(\"accept\"))\n        .amount(\"1\")\n        .reference(\"demo-001\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->transactions->travelRule->triggerTestVaspInbound([\n    'beneficiary_wallet_address' => '0xYourSandboxWallet',\n    'scenario' => 'accept',\n    'amount' => '1',\n    'reference' => 'demo-001',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.transactions.travel_rule.trigger_test_vasp_inbound(\n  beneficiary_wallet_address: \"0xYourSandboxWallet\",\n  scenario: \"accept\",\n  amount: \"1\",\n  reference: \"demo-001\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Transactions.TravelRule.TriggerTestVaspInboundAsync(new TravelRuleTestVaspInboundRequest\n{\n    BeneficiaryWalletAddress = \"0xYourSandboxWallet\",\n    Scenario = new TravelRuleTestVaspInboundRequestScenario(\"accept\"),\n    Amount = \"1\",\n    Reference = \"demo-001\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "201": {
            "description": "Transfer masuk telah dibukukan dan diputuskan. Pengulangan dengan `reference` yang sama akan mengembalikan body yang sama.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TravelRuleTestVaspInboundResponse"
                }
              }
            }
          },
          "400": {
            "description": "Body tidak valid, `scenario` yang tidak dikenal atau tidak didukung, atau aplikasi merupakan aplikasi produksi.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "409": {
            "description": "Transfer tidak dapat dibukukan, misalnya karena Travel Rule tidak diaktifkan untuk aplikasi ini.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v3/travel-rule/widget-session/": {
      "post": {
        "summary": "Buat sesi widget kepemilikan dompet",
        "description": "Buat URL/token widget kepemilikan dompet yang di-hosting. Arahkan pelanggan ke url yang dikembalikan untuk membuktikan kontrol atas dompet (penandatanganan pesan, uji Satoshi, tangkapan layar, atau deklarasi mandiri). Widget ini hanya untuk web pada rilis ini - buka url di browser sistem atau tab kustom, jangan pernah di dalam webview SDK seluler.",
        "operationId": "createTravelRuleWidgetSession",
        "x-didit-sdk": {
          "resource": "travel_rule",
          "method": "create_widget_session",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Travel Rule"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TravelRuleWidgetSessionCreate"
              },
              "example": {
                "wallet_address": "0xd3b62acb76fb27a7f8961ec40fa11746b113aca9",
                "chain": "ETH",
                "holder_name": "Jane Doe",
                "vendor_data": "user-042",
                "transaction_id": "99999999-aaaa-bbbb-cccc-dddddddddddd",
                "expires_in_minutes": 60
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST https://verification.didit.me/v3/travel-rule/widget-session/ \\\n  -H 'x-api-key: YOUR_API_KEY' -H 'Content-Type: application/json' \\\n  -d '{\"wallet_address\":\"0xd3b62acb76fb27a7f8961ec40fa11746b113aca9\",\"chain\":\"ETH\",\"holder_name\":\"Jane Doe\",\"transaction_id\":\"99999999-aaaa-bbbb-cccc-dddddddddddd\"}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.travel_rule.create_widget_session(\n    wallet_address=\"0xd3b62acb76fb27a7f8961ec40fa11746b113aca9\",\n    chain=\"ETH\",\n    holder_name=\"Jane Doe\",\n    vendor_data=\"user-042\",\n    transaction_id=\"99999999-aaaa-bbbb-cccc-dddddddddddd\",\n    expires_in_minutes=60,\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.travelRule.createWidgetSession({\n  wallet_address: \"0xd3b62acb76fb27a7f8961ec40fa11746b113aca9\",\n  chain: \"ETH\",\n  holder_name: \"Jane Doe\",\n  vendor_data: \"user-042\",\n  transaction_id: \"99999999-aaaa-bbbb-cccc-dddddddddddd\",\n  expires_in_minutes: 60,\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.TravelRule.CreateWidgetSession(ctx, didit.TravelRuleWidgetSessionCreate{\n\tWalletAddress:    didit.String(\"0xd3b62acb76fb27a7f8961ec40fa11746b113aca9\"),\n\tChain:            didit.String(\"ETH\"),\n\tHolderName:       didit.String(\"Jane Doe\"),\n\tVendorData:       didit.String(\"user-042\"),\n\tTransactionID:    didit.String(\"99999999-aaaa-bbbb-cccc-dddddddddddd\"),\n\tExpiresInMinutes: didit.Int(60),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.TravelRuleWidgetSessionCreate;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.travelRule().createWidgetSession(TravelRuleWidgetSessionCreate.builder()\n        .walletAddress(\"0xd3b62acb76fb27a7f8961ec40fa11746b113aca9\")\n        .chain(\"ETH\")\n        .holderName(\"Jane Doe\")\n        .vendorData(\"user-042\")\n        .transactionId(\"99999999-aaaa-bbbb-cccc-dddddddddddd\")\n        .expiresInMinutes(60L)\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->travelRule->createWidgetSession([\n    'wallet_address' => '0xd3b62acb76fb27a7f8961ec40fa11746b113aca9',\n    'chain' => 'ETH',\n    'holder_name' => 'Jane Doe',\n    'vendor_data' => 'user-042',\n    'transaction_id' => '99999999-aaaa-bbbb-cccc-dddddddddddd',\n    'expires_in_minutes' => 60,\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.travel_rule.create_widget_session(\n  wallet_address: \"0xd3b62acb76fb27a7f8961ec40fa11746b113aca9\",\n  chain: \"ETH\",\n  holder_name: \"Jane Doe\",\n  vendor_data: \"user-042\",\n  transaction_id: \"99999999-aaaa-bbbb-cccc-dddddddddddd\",\n  expires_in_minutes: 60\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.TravelRule.CreateWidgetSessionAsync(new TravelRuleWidgetSessionCreate\n{\n    WalletAddress = \"0xd3b62acb76fb27a7f8961ec40fa11746b113aca9\",\n    Chain = \"ETH\",\n    HolderName = \"Jane Doe\",\n    VendorData = \"user-042\",\n    TransactionId = \"99999999-aaaa-bbbb-cccc-dddddddddddd\",\n    ExpiresInMinutes = 60,\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "201": {
            "description": "Sesi widget yang diterbitkan.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TravelRuleWidgetSessionResponse"
                }
              }
            }
          },
          "400": {
            "description": "Body tidak valid: `callback_url` bukan URL http(s) absolut, `expires_in_minutes` berada di luar rentang 5 hingga 10080, `transaction_id` bukan UUID, atau kolom melebihi batas panjangnya.",
            "content": {
              "application/json": {
                "examples": {
                  "Invalid callback_url": {
                    "value": {
                      "callback_url": [
                        "callback_url must be an absolute http(s) URL."
                      ]
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "`transaction_id` tidak merujuk pada transfer Travel Rule di dalam aplikasi ini."
          }
        }
      }
    },
    "/v3/travel-rule/widget/{token}/": {
      "get": {
        "summary": "Dapatkan konteks widget kepemilikan dompet",
        "description": "Endpoint baca publik yang diidentifikasi dengan token sesi widget - tidak memerlukan kunci API. Mengembalikan konteks widget beserta status setiap bukti, sehingga Anda dapat melakukan polling untuk mendeteksi penyelesaian; completed_at menjadi non-null setelah bukti terverifikasi. Bukti SATOSHI_TEST dapat berada pada status PENDING saat depositnya terlihat di on-chain tetapi belum dikonfirmasi - tugas latar belakang secara otomatis memeriksanya kembali dan menyelesaikannya setelah deposit terkonfirmasi, sehingga tidak diperlukan tindakan klien saat menunggu. Setiap bukti memuat kolom-kolom yang dibutuhkan metodenya: deposit_address, expected_amount, dan expires_at miliknya sendiri untuk SATOSHI_TEST; challenge untuk MESSAGE_SIGNING. Utamakan webhook travel_rule.status.updated dibandingkan polling jika sesi terhubung dengan transfer.",
        "operationId": "getTravelRuleWidgetContext",
        "x-didit-sdk": {
          "resource": "travel_rule",
          "method": "retrieve_widget_context",
          "auth": "public",
          "server": false
        },
        "tags": [
          "Travel Rule"
        ],
        "security": [
          {}
        ],
        "parameters": [
          {
            "name": "token",
            "in": "path",
            "required": true,
            "description": "Token sesi yang tidak transparan yang dikembalikan saat sesi widget dibuat.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl https://verification.didit.me/v3/travel-rule/widget/{token}/"
          }
        ],
        "responses": {
          "200": {
            "description": "Konteks widget dan status bukti.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TravelRuleWidgetContext"
                }
              }
            }
          },
          "404": {
            "description": "Token tidak dikenal."
          },
          "410": {
            "description": "Sesi kedaluwarsa tanpa diselesaikan."
          }
        }
      }
    },
    "/v3/travel-rule/widget/{token}/vasps/": {
      "get": {
        "summary": "Cari VASP dari widget dompet",
        "description": "Endpoint baca publik yang diidentifikasi dengan token sesi widget, tidak memerlukan kunci API: pemilih VASP untuk widget pengguna akhir. Pencarian dan filter yang sama dengan GET /v3/travel-rule/vasps/ untuk aplikasi widget, hanya merespons identitas setiap VASP dan apakah VASP tersebut dapat dihubungi.",
        "operationId": "listTravelRuleWidgetVasps",
        "x-didit-sdk": {
          "resource": "travel_rule",
          "method": "list_widget_vasps",
          "auth": "public",
          "server": false
        },
        "tags": [
          "Travel Rule"
        ],
        "security": [
          {}
        ],
        "parameters": [
          {
            "name": "token",
            "in": "path",
            "required": true,
            "description": "Token sesi yang tidak transparan yang dikembalikan saat sesi widget dibuat.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "search",
            "in": "query",
            "schema": {
              "type": "string",
              "maxLength": 255
            },
            "description": "Fragmen nama atau alias (tidak peka huruf besar/kecil), LEI yang tepat, atau domain (example.com atau URL di dalamnya). Anggota jaringan Didit dicocokkan berdasarkan nama resmi, LEI, atau domain email kepatuhan mereka."
          },
          {
            "name": "network",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "GTR",
                "TRUST",
                "VERIFYVASP",
                "SYGNA",
                "TRISA"
              ]
            },
            "description": "Hanya entri direktori yang saat ini tercantum dalam direktori anggota suatu jaringan."
          },
          {
            "name": "jurisdiction",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Kode negara ISO 3166 alpha-2 atau alpha-3. Mengembalikan 400 untuk hal lainnya."
          },
          {
            "name": "reachable",
            "in": "query",
            "schema": {
              "type": "boolean"
            },
            "description": "true: hanya VASP yang dapat dijangkau aplikasi Anda melalui rute yang tersedia (termasuk anggota jaringan Didit). false: hanya entri direktori yang tidak dapat dijangkau saat ini."
          },
          {
            "name": "kind",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "directory",
                "didit"
              ]
            },
            "description": "Hanya entri direktori, atau hanya anggota jaringan Didit."
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 50,
              "minimum": 1
            }
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 0,
              "minimum": 0
            }
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl 'https://verification.didit.me/v3/travel-rule/widget/{token}/vasps/?search=counterparty'"
          }
        ],
        "responses": {
          "200": {
            "description": "Hasil terpaginasi dan diurutkan berdasarkan nama.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "count": {
                      "type": "integer"
                    },
                    "next": {
                      "type": "string",
                      "nullable": true
                    },
                    "previous": {
                      "type": "string",
                      "nullable": true
                    },
                    "results": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/VaspDirectoryWidgetEntry"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Filter tidak valid: body menyebutkan nama setiap kolom, misalnya jaringan atau kode negara yang tidak dikenal.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "jurisdiction": [
                    "Use an ISO 3166 alpha-2 or alpha-3 country code."
                  ],
                  "network": [
                    "\"SWIFT\" is not a valid choice."
                  ]
                }
              }
            }
          },
          "404": {
            "description": "Token tidak dikenal."
          },
          "410": {
            "description": "Sesi kedaluwarsa."
          }
        }
      },
      "post": {
        "summary": "Pilih VASP pihak lawan di widget dompet",
        "description": "Endpoint tulis publik yang diidentifikasi dengan token sesi widget, tidak memerlukan kunci API: pengguna akhir memilih VASP tujuan yang tidak dapat diidentifikasi oleh penemuan otomatis. Hanya transfer keluar dalam status COUNTERPARTY_VASP_NOT_FOUND, COUNTERPARTY_VASP_NOT_REACHABLE, atau NOT_ENOUGH_COUNTERPARTY_DATA yang menerimanya. Transfer dialihkan ke VASP tersebut dan dikirim lagi; penemuan otomatis tidak pernah menimpa pilihan tersebut.",
        "operationId": "selectTravelRuleWidgetVasp",
        "x-didit-sdk": {
          "resource": "travel_rule",
          "method": "select_widget_vasp",
          "auth": "public",
          "server": false
        },
        "tags": [
          "Travel Rule"
        ],
        "security": [
          {}
        ],
        "parameters": [
          {
            "name": "token",
            "in": "path",
            "required": true,
            "description": "Token sesi yang tidak transparan yang dikembalikan saat sesi widget dibuat.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "vasp"
                ],
                "properties": {
                  "vasp": {
                    "type": "string",
                    "format": "uuid",
                    "description": "`id` dari VASP dari `GET /v3/travel-rule/widget/{token}/vasps/`."
                  }
                }
              },
              "example": {
                "vasp": "9f1c2b34-5d6e-4f70-8a91-b2c3d4e5f607"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST https://verification.didit.me/v3/travel-rule/widget/{token}/vasps/ \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"vasp\": \"9f1c2b34-5d6e-4f70-8a91-b2c3d4e5f607\"}'"
          }
        ],
        "responses": {
          "200": {
            "description": "Pilihan telah dicatat dan transfer sedang dikirim ulang.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    },
                    "transfer_status": {
                      "type": "string",
                      "description": "Status transfer setelah pemilihan."
                    },
                    "counterparty_vasp": {
                      "type": "string",
                      "description": "Nama VASP yang dipilih oleh pengguna akhir."
                    }
                  }
                },
                "example": {
                  "detail": "Counterparty VASP selected; the transfer is being resent.",
                  "transfer_status": "AWAITING_COUNTERPARTY",
                  "counterparty_vasp": "Northwind Exchange"
                }
              }
            }
          },
          "400": {
            "description": "`vasp` tidak ada, atau tidak ada entri direktori aktif yang memiliki id tersebut.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "vasp": [
                    "No directory entry has this id."
                  ]
                }
              }
            }
          },
          "404": {
            "description": "Token tidak dikenal."
          },
          "409": {
            "description": "Sesi widget tidak ditautkan ke transfer Travel Rule, atau transfer tersebut bukan transfer keluar dengan status yang menerima pihak lawan."
          },
          "410": {
            "description": "Sesi kedaluwarsa."
          }
        }
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/vendor-users/toggle-ongoing-monitoring/": {
      "patch": {
        "summary": "Aktifkan/nonaktifkan Pemantauan AML Berkelanjutan untuk pengguna",
        "description": "Mengaktifkan atau menonaktifkan pemantauan AML berkelanjutan di tingkat pengguna. Tepat satu Skrining AML yang dipantau disimpan per pengguna; pengguna tanpa Skrining AML sama sekali (misalnya pengguna hasil impor) akan dibuatkan dan menjalani Skrining AML terlebih dahulu, ditagih sebagai Skrining AML reguler. Tetapkan estimate_only untuk melihat pratinjau jumlah dan biaya tanpa menyimpan data. Batch berisi 20 atau kurang diselesaikan secara inline (200, COMPLETED); batch yang lebih besar mengembalikan 202 dan berjalan secara asinkron.",
        "operationId": "toggle_vendor_users_ongoing_monitoring",
        "x-didit-sdk": {
          "resource": "users",
          "method": "set_ongoing_monitoring",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Users"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID organisasi."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID aplikasi."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/OngoingMonitoringToggleRequest"
              },
              "example": {
                "is_enabled": true,
                "didit_internal_id_list": [
                  "5b9a0000-0000-4000-8000-00000000f00d"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Estimasi (saat estimate_only) atau tugas yang selesai untuk batch kecil yang diproses secara inline.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OngoingMonitoringToggleResult"
                }
              }
            }
          },
          "202": {
            "description": "Batch yang lebih besar diproses secara asinkron; lakukan polling pada endpoint job dengan job_id yang dikembalikan.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OngoingMonitoringJob"
                }
              }
            }
          },
          "403": {
            "description": "Hak istimewa write:sessions tidak ada, atau saldo tidak mencukupi untuk mengaktifkan (perkiraan disertakan dalam badan kesalahan)."
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.users.set_ongoing_monitoring(\n    is_enabled=True,\n    didit_internal_id_list=[\"5b9a0000-0000-4000-8000-00000000f00d\"],\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.users.setOngoingMonitoring({\n  is_enabled: true,\n  didit_internal_id_list: [\"5b9a0000-0000-4000-8000-00000000f00d\"],\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Users.SetOngoingMonitoring(ctx, didit.OngoingMonitoringToggleRequest{\n\tIsEnabled:           true,\n\tDiditInternalIDList: didit.Some([]string{\"5b9a0000-0000-4000-8000-00000000f00d\"}),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.List;\nimport me.didit.Didit;\nimport me.didit.types.OngoingMonitoringToggleRequest;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.users().setOngoingMonitoring(OngoingMonitoringToggleRequest.builder()\n        .isEnabled(true)\n        .diditInternalIdList(List.of(\"5b9a0000-0000-4000-8000-00000000f00d\"))\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->users->setOngoingMonitoring([\n    'is_enabled' => true,\n    'didit_internal_id_list' => ['5b9a0000-0000-4000-8000-00000000f00d'],\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.users.set_ongoing_monitoring(\n  is_enabled: true,\n  didit_internal_id_list: [\"5b9a0000-0000-4000-8000-00000000f00d\"]\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Users.SetOngoingMonitoringAsync(new OngoingMonitoringToggleRequest\n{\n    IsEnabled = true,\n    DiditInternalIdList = new string[] { \"5b9a0000-0000-4000-8000-00000000f00d\" },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/vendor-users/toggle-ongoing-monitoring/{job_id}/": {
      "get": {
        "summary": "Dapatkan tugas pemantauan AML berkelanjutan",
        "description": "Progres dan penghitung per-hasil dari tugas pengaktifan dan penonaktifan pemantauan. Lakukan polling setiap beberapa detik selama status masih PENDING atau PROCESSING.",
        "operationId": "get_vendor_users_ongoing_monitoring_job",
        "x-didit-sdk": {
          "resource": "users",
          "method": "retrieve_ongoing_monitoring_job",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Users"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID organisasi."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID aplikasi."
          },
          {
            "name": "job_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID tugas pemantauan yang dikembalikan oleh endpoint toggle."
          }
        ],
        "responses": {
          "200": {
            "description": "Pekerjaan tersebut.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OngoingMonitoringJob"
                }
              }
            }
          },
          "404": {
            "description": "Job tidak dikenal untuk aplikasi ini."
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.users.retrieve_ongoing_monitoring_job(\n    \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.users.retrieveOngoingMonitoringJob(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Users.RetrieveOngoingMonitoringJob(ctx, \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.users().retrieveOngoingMonitoringJob(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->users->retrieveOngoingMonitoringJob('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.users.retrieve_ongoing_monitoring_job(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Users.RetrieveOngoingMonitoringJobAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/vendor-businesses/toggle-ongoing-monitoring/": {
      "patch": {
        "summary": "Aktifkan/nonaktifkan Pemantauan AML Berkelanjutan untuk bisnis",
        "description": "Padanan tingkat bisnis dari toggle pengguna: satu Skrining AML yang dipantau per bisnis, dengan bisnis yang belum memiliki Skrining AML diskrining terlebih dahulu (entitas perusahaan). Kontrak estimate_only, inline fast-path, dan tugas asinkron yang sama.",
        "operationId": "toggle_vendor_businesses_ongoing_monitoring",
        "x-didit-sdk": {
          "resource": "businesses",
          "method": "set_ongoing_monitoring",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Businesses"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID organisasi."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID aplikasi."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/OngoingMonitoringToggleRequest"
              },
              "example": {
                "is_enabled": true,
                "didit_internal_id_list": [
                  "b0000000-0000-4000-8000-0000000000b1"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Estimasi (saat estimate_only) atau tugas yang selesai untuk batch kecil yang diproses secara inline.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OngoingMonitoringToggleResult"
                }
              }
            }
          },
          "202": {
            "description": "Batch yang lebih besar diproses secara asinkron; lakukan polling pada endpoint job dengan job_id yang dikembalikan.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OngoingMonitoringJob"
                }
              }
            }
          },
          "403": {
            "description": "Hak istimewa write:sessions tidak ada, atau saldo tidak mencukupi untuk mengaktifkan (perkiraan disertakan dalam badan kesalahan)."
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.businesses.set_ongoing_monitoring(\n    is_enabled=True,\n    didit_internal_id_list=[\"b0000000-0000-4000-8000-0000000000b1\"],\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.businesses.setOngoingMonitoring({\n  is_enabled: true,\n  didit_internal_id_list: [\"b0000000-0000-4000-8000-0000000000b1\"],\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Businesses.SetOngoingMonitoring(ctx, didit.OngoingMonitoringToggleRequest{\n\tIsEnabled:           true,\n\tDiditInternalIDList: didit.Some([]string{\"b0000000-0000-4000-8000-0000000000b1\"}),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.List;\nimport me.didit.Didit;\nimport me.didit.types.OngoingMonitoringToggleRequest;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.businesses().setOngoingMonitoring(OngoingMonitoringToggleRequest.builder()\n        .isEnabled(true)\n        .diditInternalIdList(List.of(\"b0000000-0000-4000-8000-0000000000b1\"))\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->businesses->setOngoingMonitoring([\n    'is_enabled' => true,\n    'didit_internal_id_list' => ['b0000000-0000-4000-8000-0000000000b1'],\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.businesses.set_ongoing_monitoring(\n  is_enabled: true,\n  didit_internal_id_list: [\"b0000000-0000-4000-8000-0000000000b1\"]\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Businesses.SetOngoingMonitoringAsync(new OngoingMonitoringToggleRequest\n{\n    IsEnabled = true,\n    DiditInternalIdList = new string[] { \"b0000000-0000-4000-8000-0000000000b1\" },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/vendor-businesses/toggle-ongoing-monitoring/{job_id}/": {
      "get": {
        "summary": "Dapatkan tugas pemantauan AML berkelanjutan",
        "description": "Progres dan penghitung per-hasil dari tugas pengaktifan dan penonaktifan pemantauan. Lakukan polling setiap beberapa detik selama status masih PENDING atau PROCESSING.",
        "operationId": "get_vendor_businesses_ongoing_monitoring_job",
        "x-didit-sdk": {
          "resource": "businesses",
          "method": "retrieve_ongoing_monitoring_job",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Businesses"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID organisasi."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID aplikasi."
          },
          {
            "name": "job_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID tugas pemantauan yang dikembalikan oleh endpoint toggle."
          }
        ],
        "responses": {
          "200": {
            "description": "Pekerjaan tersebut.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OngoingMonitoringJob"
                }
              }
            }
          },
          "404": {
            "description": "Job tidak dikenal untuk aplikasi ini."
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.businesses.retrieve_ongoing_monitoring_job(\n    \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.businesses.retrieveOngoingMonitoringJob(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Businesses.RetrieveOngoingMonitoringJob(ctx, \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.businesses().retrieveOngoingMonitoringJob(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->businesses->retrieveOngoingMonitoringJob('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.businesses.retrieve_ongoing_monitoring_job(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Businesses.RetrieveOngoingMonitoringJobAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/businesses/toggle-ongoing-monitoring/": {
      "patch": {
        "summary": "Aktifkan/nonaktifkan Pemantauan AML Berkelanjutan untuk sesi bisnis",
        "description": "Tombol pengalih tingkat sesi untuk verifikasi KYB, diterapkan berdasarkan nomor sesi. Sesi tanpa Skrining AML akan dibuatkan satu dan dilampirkan ke sesi itu sendiri. Memiliki estimate_only, jalur cepat inline, dan kontrak tugas asinkron yang sama dengan endpoint tingkat pengguna. Menggantikan perilaku sinkron lama yang melewati sesi tanpa Skrining AML.",
        "operationId": "toggle_business_sessions_ongoing_monitoring",
        "x-didit-sdk": {
          "resource": "businesses",
          "method": "set_session_ongoing_monitoring",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Businesses"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID organisasi."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID aplikasi."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "is_enabled"
                ],
                "properties": {
                  "is_enabled": {
                    "type": "boolean",
                    "description": "true untuk mengaktifkan pemantauan, false untuk menonaktifkannya."
                  },
                  "estimate_only": {
                    "type": "boolean",
                    "default": false,
                    "description": "Jika true, mengembalikan estimasi biaya dan tidak melakukan penulisan data."
                  },
                  "update_all": {
                    "type": "boolean",
                    "default": false,
                    "description": "Terapkan ke setiap entitas aplikasi (dibatasi oleh parameter filter_* jika ada)."
                  },
                  "filter_search": {
                    "type": "string"
                  },
                  "filter_status": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  },
                  "filter_country": {
                    "type": "string"
                  },
                  "filter_date_from": {
                    "type": "string",
                    "format": "date"
                  },
                  "filter_date_to": {
                    "type": "string",
                    "format": "date"
                  },
                  "session_numbers": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Nomor sesi bisnis yang statusnya akan diubah. Wajib diisi kecuali update_all (atau alias lawas toggle_all) bernilai true."
                  },
                  "toggle_all": {
                    "type": "boolean",
                    "default": false,
                    "description": "Alias lama dari update_all."
                  },
                  "filter_workflow_id": {
                    "type": "string"
                  }
                }
              },
              "example": {
                "is_enabled": true,
                "session_numbers": [
                  "1001",
                  "1002"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Estimasi (saat estimate_only) atau tugas yang selesai untuk batch kecil yang diproses secara inline.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OngoingMonitoringToggleResult"
                }
              }
            }
          },
          "202": {
            "description": "Batch yang lebih besar diproses secara asinkron; lakukan polling pada endpoint job dengan job_id yang dikembalikan.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OngoingMonitoringJob"
                }
              }
            }
          },
          "403": {
            "description": "Hak istimewa write:sessions tidak ada, atau saldo tidak mencukupi untuk mengaktifkan (perkiraan disertakan dalam badan kesalahan)."
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.businesses.set_session_ongoing_monitoring(\n    is_enabled=True,\n    session_numbers=[\"1001\", \"1002\"],\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.businesses.setSessionOngoingMonitoring({\n  is_enabled: true,\n  session_numbers: [\"1001\", \"1002\"],\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Businesses.SetSessionOngoingMonitoring(ctx, didit.BusinessesSetSessionOngoingMonitoringParams{\n\tIsEnabled:      true,\n\tSessionNumbers: didit.Some([]string{\"1001\", \"1002\"}),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.List;\nimport me.didit.Didit;\nimport me.didit.types.BusinessesSetSessionOngoingMonitoringParams;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.businesses().setSessionOngoingMonitoring(BusinessesSetSessionOngoingMonitoringParams.builder()\n        .isEnabled(true)\n        .sessionNumbers(List.of(\"1001\", \"1002\"))\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->businesses->setSessionOngoingMonitoring([\n    'is_enabled' => true,\n    'session_numbers' => ['1001', '1002'],\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.businesses.set_session_ongoing_monitoring(\n  is_enabled: true,\n  session_numbers: [\"1001\", \"1002\"]\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Businesses.SetSessionOngoingMonitoringAsync(new BusinessesSetSessionOngoingMonitoringParams\n{\n    IsEnabled = true,\n    SessionNumbers = new string[] { \"1001\", \"1002\" },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/businesses/toggle-ongoing-monitoring/{job_id}/": {
      "get": {
        "summary": "Dapatkan tugas pemantauan AML berkelanjutan",
        "description": "Progres dan penghitung per-hasil dari tugas pengaktifan dan penonaktifan pemantauan. Lakukan polling setiap beberapa detik selama status masih PENDING atau PROCESSING.",
        "operationId": "get_business_sessions_ongoing_monitoring_job",
        "x-didit-sdk": {
          "resource": "businesses",
          "method": "retrieve_session_ongoing_monitoring_job",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Businesses"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID organisasi."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID aplikasi."
          },
          {
            "name": "job_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID tugas pemantauan yang dikembalikan oleh endpoint toggle."
          }
        ],
        "responses": {
          "200": {
            "description": "Pekerjaan tersebut.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OngoingMonitoringJob"
                }
              }
            }
          },
          "404": {
            "description": "Job tidak dikenal untuk aplikasi ini."
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.businesses.retrieve_session_ongoing_monitoring_job(\n    \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.businesses.retrieveSessionOngoingMonitoringJob(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Businesses.RetrieveSessionOngoingMonitoringJob(ctx, \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.businesses().retrieveSessionOngoingMonitoringJob(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->businesses->retrieveSessionOngoingMonitoringJob('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.businesses.retrieve_session_ongoing_monitoring_job(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Businesses.RetrieveSessionOngoingMonitoringJobAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/cases/": {
      "get": {
        "summary": "Daftar kasus",
        "description": "Daftar kasus untuk aplikasi, terbaru lebih dahulu. Mendukung pemfilteran, pencarian, dan pengurutan; lihat parameter kueri. Dipaginasi dengan `limit`/`offset`.",
        "operationId": "list_cases",
        "x-didit-sdk": {
          "resource": "cases",
          "method": "list",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Cases"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID organisasi."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID aplikasi."
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 50,
              "minimum": 1
            },
            "description": "Ukuran halaman. Nilai default-nya 50."
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 0,
              "minimum": 0
            },
            "description": "Offset berbasis nol dari rekaman pertama."
          },
          {
            "name": "status__in",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Status yang dipisahkan dengan koma untuk disertakan, misalnya OPEN,AWAITING_USER."
          },
          {
            "name": "priority",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Prioritas yang dipisahkan dengan koma untuk disertakan."
          },
          {
            "name": "source__in",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Sumber yang dipisahkan dengan koma untuk disertakan."
          },
          {
            "name": "blueprint",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Filter kasus pada cetak biru ini."
          },
          {
            "name": "assigned_to",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Filter kasus yang ditetapkan untuk pengguna ini."
          },
          {
            "name": "unassigned",
            "in": "query",
            "schema": {
              "type": "boolean"
            },
            "description": "true untuk kasus yang belum ditetapkan, false untuk kasus yang sudah ditetapkan."
          },
          {
            "name": "tag",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Filter kasus yang memuat tag ini secara persis."
          },
          {
            "name": "search",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Mencocokkan judul, case_number, tag, nama/UUID/ID eksternal subjek, UUID sesi tertaut, atau UUID transaksi tertaut."
          },
          {
            "name": "date_from",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date"
            },
            "description": "Batas bawah tanggal pembuatan (inklusif)."
          },
          {
            "name": "date_to",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date"
            },
            "description": "Batas atas tanggal pembuatan (inklusif)."
          },
          {
            "name": "due_before",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Batas atas due_at."
          },
          {
            "name": "overdue",
            "in": "query",
            "schema": {
              "type": "boolean"
            },
            "description": "true untuk hanya mengembalikan kasus terbuka/menunggu pengguna yang sudah melewati batas waktu."
          },
          {
            "name": "ordering",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "created_at",
                "-created_at",
                "due_at",
                "-due_at"
              ],
              "default": "-created_at"
            },
            "description": "Urutan pengurutan. due_at mengurutkan nilai null di akhir."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/cases/?status__in=OPEN,AWAITING_USER&ordering=-due_at' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nfor item in client.cases.list():\n    print(item)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nfor await (const item of didit.cases.list()) {\n  console.log(item);\n}"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\niter := client.Cases.ListAutoPaging(ctx, didit.CasesListParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nfor (var item : client.cases().list()) {\n    System.out.println(item);\n}"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\nforeach ($didit->cases->list() as $item) {\n    print_r($item->toArray());\n}"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\ndidit.cases.list.auto_paging_each do |item|\n  puts item.to_h\nend"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.Cases.ListAsync())\n{\n    Console.WriteLine(JsonSerializer.Serialize(item));\n}"
          }
        ],
        "responses": {
          "200": {
            "description": "Daftar kasus berpaginasi.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "count": {
                      "type": "integer",
                      "description": "Jumlah baris yang cocok. Tepat hingga 100, dibatasi maksimal 100 setelahnya demi performa. Andalkan nilai `next` yang null untuk mendeteksi halaman terakhir."
                    },
                    "next": {
                      "type": "string",
                      "nullable": true,
                      "description": "URL absolut halaman berikutnya, atau null."
                    },
                    "previous": {
                      "type": "string",
                      "nullable": true,
                      "description": "URL absolut halaman sebelumnya, atau null."
                    },
                    "results": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/CaseListItem"
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      },
      "post": {
        "summary": "Buat kasus",
        "description": "Buat kasus yang ditautkan ke tepat satu subjek (pengguna atau bisnis), secara langsung atau dengan memperoleh subjek dari tautan sesi/transaksi yang dilampirkan. Sumber selalu bernilai `MANUAL` untuk kasus yang dibuat melalui API.",
        "operationId": "create_case",
        "x-didit-sdk": {
          "resource": "cases",
          "method": "create",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Cases"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID organisasi."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID aplikasi."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "title"
                ],
                "properties": {
                  "title": {
                    "type": "string",
                    "maxLength": 255
                  },
                  "blueprint": {
                    "type": "string",
                    "format": "uuid",
                    "nullable": true,
                    "description": "UUID CaseBlueprint. Jangan sertakan jika tanpa blueprint."
                  },
                  "priority": {
                    "type": "string",
                    "enum": [
                      "LOW",
                      "MEDIUM",
                      "HIGH"
                    ],
                    "default": "MEDIUM"
                  },
                  "due_at": {
                    "type": "string",
                    "format": "date-time",
                    "nullable": true
                  },
                  "tags": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  },
                  "subject": {
                    "type": "object",
                    "description": "Wajib kecuali jika links disediakan; tepat satu subjek kasus.",
                    "properties": {
                      "type": {
                        "type": "string",
                        "enum": [
                          "user",
                          "business"
                        ]
                      },
                      "uuid": {
                        "type": "string",
                        "format": "uuid"
                      }
                    }
                  },
                  "links": {
                    "type": "array",
                    "description": "Sesi/sesi bisnis/transaksi yang dilampirkan saat pembuatan, mis. [{\"entity_type\": \"transaction\", \"entity_uuid\": \"...\"}]. Jika subjek dihilangkan, subjek akan diambil dari pemilik tautan pertama.",
                    "items": {
                      "type": "object"
                    }
                  },
                  "assigned_to": {
                    "type": "string",
                    "format": "uuid",
                    "nullable": true,
                    "description": "UUID pengguna yang akan segera ditetapkan."
                  },
                  "review_duplicates": {
                    "type": "boolean",
                    "default": false,
                    "description": "Periksa ulang investigasi yang ada sebelum membuat kasus. Jika bernilai true, subjek dengan kasus yang sudah ada memerlukan separate_incident_reason yang tidak kosong. Konsol selalu mengaktifkan perlindungan ini. Mengabaikannya akan mempertahankan perilaku API yang ada."
                  },
                  "separate_incident_reason": {
                    "type": "string",
                    "maxLength": 1000
                  },
                  "source_context": {
                    "$ref": "#/components/schemas/CaseDuplicateCaseFraudSourceContextRequest"
                  }
                }
              },
              "example": {
                "title": "Manual - Jane Doe",
                "blueprint": "b1de0000-0000-4000-8000-000000000002",
                "priority": "HIGH",
                "subject": {
                  "type": "user",
                  "uuid": "5b9a0000-0000-4000-8000-00000000f00d"
                },
                "tags": [
                  "review"
                ]
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/cases/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"title\": \"Manual - Jane Doe\", \"blueprint\": \"b1de0000-0000-4000-8000-000000000002\", \"priority\": \"HIGH\", \"subject\": {\"type\": \"user\", \"uuid\": \"5b9a0000-0000-4000-8000-00000000f00d\"}, \"tags\": [\"review\"]}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.create(\n    title=\"Manual - Jane Doe\",\n    blueprint=\"b1de0000-0000-4000-8000-000000000002\",\n    priority=\"HIGH\",\n    tags=[\"review\"],\n    subject={\n        \"type\": \"user\",\n        \"uuid\": \"5b9a0000-0000-4000-8000-00000000f00d\",\n    },\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.create({\n  title: \"Manual - Jane Doe\",\n  blueprint: \"b1de0000-0000-4000-8000-000000000002\",\n  priority: \"HIGH\",\n  tags: [\"review\"],\n  subject: {\n    type: \"user\",\n    uuid: \"5b9a0000-0000-4000-8000-00000000f00d\",\n  },\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.Create(ctx, didit.CasesCreateParams{\n\tTitle:     \"Manual - Jane Doe\",\n\tBlueprint: didit.String(\"b1de0000-0000-4000-8000-000000000002\"),\n\tPriority:  didit.Some(didit.CasesCreateParamsPriority(\"HIGH\")),\n\tTags:      didit.Some([]string{\"review\"}),\n\tSubject: didit.Some(didit.CasesCreateParamsSubject{\n\t\tType: didit.Some(didit.CasesCreateParamsSubjectType(\"user\")),\n\t\tUUID: didit.String(\"5b9a0000-0000-4000-8000-00000000f00d\"),\n\t}),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.List;\nimport me.didit.Didit;\nimport me.didit.types.CasesCreateParams;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().create(CasesCreateParams.builder()\n        .title(\"Manual - Jane Doe\")\n        .blueprint(\"b1de0000-0000-4000-8000-000000000002\")\n        .priority(CasesCreateParams.Priority.of(\"HIGH\"))\n        .tags(List.of(\"review\"))\n        .subject(CasesCreateParams.Subject.builder()\n                .type(CasesCreateParams.Subject.Type.of(\"user\"))\n                .uuid(\"5b9a0000-0000-4000-8000-00000000f00d\")\n                .build())\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->cases->create([\n    'title' => 'Manual - Jane Doe',\n    'blueprint' => 'b1de0000-0000-4000-8000-000000000002',\n    'priority' => 'HIGH',\n    'tags' => ['review'],\n    'subject' => [\n        'type' => 'user',\n        'uuid' => '5b9a0000-0000-4000-8000-00000000f00d',\n    ],\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.create(\n  title: \"Manual - Jane Doe\",\n  blueprint: \"b1de0000-0000-4000-8000-000000000002\",\n  priority: \"HIGH\",\n  tags: [\"review\"],\n  subject: {\n    type: \"user\",\n    uuid: \"5b9a0000-0000-4000-8000-00000000f00d\",\n  }\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.CreateAsync(new CasesCreateParams\n{\n    Title = \"Manual - Jane Doe\",\n    Blueprint = \"b1de0000-0000-4000-8000-000000000002\",\n    Priority = new CasesCreateParamsPriority(\"HIGH\"),\n    Tags = new string[] { \"review\" },\n    Subject = new CasesCreateParamsSubject\n    {\n        Type = new CasesCreateParamsSubjectType(\"user\"),\n        Uuid = \"5b9a0000-0000-4000-8000-00000000f00d\",\n    },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "201": {
            "description": "Kasus dibuat.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CaseDetail"
                }
              }
            }
          },
          "400": {
            "description": "Baik subject maupun links tidak diberikan, atau subject/blueprint/assignee tidak ditemukan.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "409": {
            "description": "Peninjauan duplikat diaktifkan dan kasus yang sudah ada ditemukan tanpa alasan insiden terpisah. Tidak ada kasus yang dibuat."
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/cases/{case_uuid}/": {
      "get": {
        "summary": "Dapatkan kasus",
        "description": "Ambil kasus beserta subjek, blueprint, catatan, event, tautan, dan checklist-nya.",
        "operationId": "get_case",
        "x-didit-sdk": {
          "resource": "cases",
          "method": "retrieve",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Cases"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID organisasi."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID aplikasi."
          },
          {
            "name": "case_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "c1a5e000-0000-4000-8000-000000000001"
            },
            "description": "UUID kasus."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/cases/c1a5e000-0000-4000-8000-000000000001/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.retrieve(\n    \"c1a5e000-0000-4000-8000-000000000001\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.retrieve(\"c1a5e000-0000-4000-8000-000000000001\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.Retrieve(ctx, \"c1a5e000-0000-4000-8000-000000000001\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().retrieve(\"c1a5e000-0000-4000-8000-000000000001\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->cases->retrieve('c1a5e000-0000-4000-8000-000000000001');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.retrieve(\"c1a5e000-0000-4000-8000-000000000001\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.RetrieveAsync(\"c1a5e000-0000-4000-8000-000000000001\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "Detail kasus.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CaseDetail"
                }
              }
            }
          },
          "404": {
            "description": "Kasus (atau resource bersarang) tidak ditemukan di aplikasi ini.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      },
      "patch": {
        "summary": "Perbarui kasus",
        "description": "Perbarui judul, prioritas, batas waktu, tag, atau tim peninjau yang menangani kasus. Kirimkan hanya kolom yang ingin Anda ubah; kolom yang diabaikan akan mempertahankan nilainya. `tags` menggantikan seluruh daftar tag. `team` menerima uuid dari tim peninjau aktif di aplikasi ini (lihat daftarnya dengan `GET .../cases/teams/`), atau null untuk menghapus tim. Memerlukan kunci API akses penuh, atau `write:cases` untuk anggota konsol: kunci dengan akses terbatas akan menerima 403. Mencatat event PRIORITY_CHANGED, DUE_DATE_CHANGED, TAG_ADDED, TAG_REMOVED, dan TEAM_CHANGED yang sesuai; perubahan judul disimpan tanpa event linimasa. Mengembalikan kasus yang diperbarui.",
        "operationId": "update_case",
        "x-didit-sdk": {
          "resource": "cases",
          "method": "update",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Cases"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID organisasi."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID aplikasi."
          },
          {
            "name": "case_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "c1a5e000-0000-4000-8000-000000000001"
            },
            "description": "UUID kasus."
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "title": {
                    "type": "string",
                    "maxLength": 255,
                    "description": "Judul kasus baru."
                  },
                  "priority": {
                    "type": "string",
                    "enum": [
                      "LOW",
                      "MEDIUM",
                      "HIGH"
                    ]
                  },
                  "due_at": {
                    "type": "string",
                    "format": "date-time",
                    "nullable": true,
                    "description": "Batas waktu baru. Kirim null untuk menghapusnya."
                  },
                  "tags": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Daftar tag lengkap. Ini menggantikan tag saat ini."
                  },
                  "team": {
                    "type": "string",
                    "format": "uuid",
                    "nullable": true,
                    "description": "UUID tim peninjau yang memiliki kasus tersebut. Harus berupa tim aktif dari aplikasi ini. Kirim null untuk mengosongkan tim."
                  }
                }
              },
              "examples": {
                "Change priority and deadline": {
                  "value": {
                    "priority": "HIGH",
                    "due_at": "2026-11-01T00:00:00Z"
                  }
                },
                "Move the case to a team": {
                  "value": {
                    "team": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
                  }
                },
                "Clear the team": {
                  "value": {
                    "team": null
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X PATCH 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/cases/c1a5e000-0000-4000-8000-000000000001/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"priority\": \"HIGH\", \"due_at\": \"2026-08-01T00:00:00Z\"}'"
          },
          {
            "lang": "curl",
            "label": "curl (change team)",
            "source": "curl -X PATCH 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/cases/c1a5e000-0000-4000-8000-000000000001/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"team\": \"3fa85f64-5717-4562-b3fc-2c963f66afa6\"}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.update(\n    \"c1a5e000-0000-4000-8000-000000000001\",\n    priority=\"HIGH\",\n    due_at=\"2026-11-01T00:00:00Z\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.update(\"c1a5e000-0000-4000-8000-000000000001\", {\n  priority: \"HIGH\",\n  due_at: \"2026-11-01T00:00:00Z\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.Update(ctx, \"c1a5e000-0000-4000-8000-000000000001\", didit.CasesUpdateParams{\n\tPriority: didit.Some(didit.CasesUpdateParamsPriority(\"HIGH\")),\n\tDueAt:    didit.Time(time.Date(2026, 11, 1, 0, 0, 0, 0, time.UTC)),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.time.OffsetDateTime;\nimport me.didit.Didit;\nimport me.didit.types.CasesUpdateParams;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().update(\"c1a5e000-0000-4000-8000-000000000001\", CasesUpdateParams.builder()\n        .priority(CasesUpdateParams.Priority.of(\"HIGH\"))\n        .dueAt(OffsetDateTime.parse(\"2026-11-01T00:00:00Z\"))\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->cases->update('c1a5e000-0000-4000-8000-000000000001', [\n    'priority' => 'HIGH',\n    'due_at' => '2026-11-01T00:00:00Z',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.update(\n  \"c1a5e000-0000-4000-8000-000000000001\",\n  priority: \"HIGH\",\n  due_at: \"2026-11-01T00:00:00Z\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.UpdateAsync(\"c1a5e000-0000-4000-8000-000000000001\", new CasesUpdateParams\n{\n    Priority = new CasesUpdateParamsPriority(\"HIGH\"),\n    DueAt = DateTimeOffset.Parse(\"2026-11-01T00:00:00Z\"),\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "Kasus yang diperbarui.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CaseDetail"
                }
              }
            }
          },
          "400": {
            "description": "Kolom gagal divalidasi. Body diberi kunci berdasarkan nama kolom. `team` ditolak jika bukan merupakan tim peninjau aktif dari aplikasi ini.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Team not active in this application": {
                    "value": {
                      "team": [
                        "Choose an active team of this application."
                      ]
                    }
                  },
                  "Invalid priority": {
                    "value": {
                      "priority": [
                        "\"URGENT\" is not a valid choice."
                      ]
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Kunci API milik aplikasi lain, atau merupakan kunci dengan akses terbatas: Endpoint Cases memerlukan kunci akses penuh. Token anggota konsol memerlukan `write:cases`.",
            "content": {
              "application/json": {
                "examples": {
                  "Restricted API Key": {
                    "summary": "Kunci API dengan akses terbatas",
                    "value": {
                      "detail": "This API key has no access to this endpoint."
                    }
                  },
                  "Missing Privilege": {
                    "summary": "Anggota konsol tanpa write:cases, atau kunci dari aplikasi lain",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Kasus tidak ditemukan di aplikasi ini.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "detail": "No Case matches the given query."
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      },
      "delete": {
        "summary": "Hapus kasus",
        "description": "Hapus kasus secara permanen. Draf laporan regulasi di dalamnya akan dihapus bersama kasus tersebut. Verifikasi, individu, perusahaan, dan transaksi yang tertaut tidak akan dihapus. Tidak ada endpoint untuk membatalkan penghapusan.\n\nJika kasus memiliki laporan regulasi yang telah difinalisasi, seluruh permintaan akan ditolak dengan `409` dan tidak ada yang dihapus. Isi respons menggunakan `code: in_filed_report` dan menyebutkan setiap laporan beserta `uuid`, `report_number`, `report_type`, dan `case_uuid`. Hapus laporan tersebut, lalu ulangi permintaan.",
        "operationId": "delete_case",
        "x-didit-sdk": {
          "resource": "cases",
          "method": "delete",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Cases"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID organisasi."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID aplikasi."
          },
          {
            "name": "case_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "c1a5e000-0000-4000-8000-000000000001"
            },
            "description": "UUID kasus."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X DELETE 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/cases/c1a5e000-0000-4000-8000-000000000001/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nclient.cases.delete(\n    \"c1a5e000-0000-4000-8000-000000000001\",\n)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nawait didit.cases.delete(\"c1a5e000-0000-4000-8000-000000000001\");"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nif err := client.Cases.Delete(ctx, \"c1a5e000-0000-4000-8000-000000000001\"); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nclient.cases().delete(\"c1a5e000-0000-4000-8000-000000000001\");"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$didit->cases->delete('c1a5e000-0000-4000-8000-000000000001');"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\ndidit.cases.delete(\"c1a5e000-0000-4000-8000-000000000001\")"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nawait client.Cases.DeleteAsync(\"c1a5e000-0000-4000-8000-000000000001\");"
          }
        ],
        "responses": {
          "204": {
            "description": "Kasus dihapus."
          },
          "403": {
            "description": "Kunci tidak dapat menghapus kasus. Tindakan ini memerlukan kunci akses penuh dengan `write:cases`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Kasus tidak ada dalam aplikasi ini atau sudah dihapus.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "Kasus memiliki laporan regulasi yang sudah final. Tidak ada yang dihapus.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InFiledReportError"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/cases/{case_uuid}/assign/": {
      "post": {
        "summary": "Tetapkan atau batalkan penetapan kasus",
        "description": "Tetapkan kasus ke pengguna, atau batalkan penetapannya dengan mengirimkan assignee_user_id: null. assignee_email/assignee_name secara otomatis membuat baris Pengguna saat penerima tugas belum ada.",
        "operationId": "assign_case",
        "x-didit-sdk": {
          "resource": "cases",
          "method": "assign",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Cases"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID organisasi."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID aplikasi."
          },
          {
            "name": "case_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "c1a5e000-0000-4000-8000-000000000001"
            },
            "description": "UUID kasus."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "assignee_user_id"
                ],
                "properties": {
                  "assignee_user_id": {
                    "type": "string",
                    "format": "uuid",
                    "nullable": true,
                    "description": "null untuk membatalkan penetapan."
                  },
                  "assignee_email": {
                    "type": "string",
                    "format": "email",
                    "nullable": true
                  },
                  "assignee_name": {
                    "type": "string",
                    "nullable": true
                  }
                }
              },
              "example": {
                "assignee_user_id": "9a000000-0000-4000-8000-0000000000aa"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/cases/c1a5e000-0000-4000-8000-000000000001/assign/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"assignee_user_id\": \"9a000000-0000-4000-8000-0000000000aa\"}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.assign(\n    \"c1a5e000-0000-4000-8000-000000000001\",\n    assignee_user_id=\"9a000000-0000-4000-8000-0000000000aa\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.assign(\"c1a5e000-0000-4000-8000-000000000001\", {\n  assignee_user_id: \"9a000000-0000-4000-8000-0000000000aa\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.Assign(ctx, \"c1a5e000-0000-4000-8000-000000000001\", didit.CasesAssignParams{\n\tAssigneeUserID: didit.String(\"9a000000-0000-4000-8000-0000000000aa\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.CasesAssignParams;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().assign(\"c1a5e000-0000-4000-8000-000000000001\", CasesAssignParams.builder()\n        .assigneeUserId(\"9a000000-0000-4000-8000-0000000000aa\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->cases->assign('c1a5e000-0000-4000-8000-000000000001', [\n    'assignee_user_id' => '9a000000-0000-4000-8000-0000000000aa',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.assign(\n  \"c1a5e000-0000-4000-8000-000000000001\",\n  assignee_user_id: \"9a000000-0000-4000-8000-0000000000aa\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.AssignAsync(\"c1a5e000-0000-4000-8000-000000000001\", new CasesAssignParams\n{\n    AssigneeUserId = \"9a000000-0000-4000-8000-0000000000aa\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "Kasus ditetapkan/tidak ditetapkan.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CaseDetail"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/cases/{case_uuid}/resolve/": {
      "post": {
        "summary": "Selesaikan kasus",
        "description": "Selesaikan kasus dengan salah satu dari lima resolusi: FALSE_POSITIVE (tidak ditemukan masalah), VALID_THREAT (masalah terkonfirmasi), INCONCLUSIVE, REQUIREMENTS_NOT_MET, atau REQUIREMENTS_SATISFIED. Diblokir dengan 400 jika checklist blueprint tidak opsional dan masih ada item yang belum selesai, atau jika blueprint mewajibkan catatan resolusi dan tidak ada yang diberikan. Saat blueprint kasus memiliki langkah pemeriksa four-eyes (four_eyes_checker_blueprint), resolusi ditangguhkan (case.pending_resolution) dan kasus dipindahkan ke blueprint pemeriksa alih-alih langsung diselesaikan; petugas lain harus memanggil approve atau reject-approval. Kirim resolusi four-eyes sebagai anggota konsol: resolusi yang dikirim oleh kunci API tidak memiliki pembuat yang tercatat, sehingga approve dan reject-approval mengembalikan 403 untuk setiap pemanggil. Pada blueprint four-eyes, Anda dapat menentukan anggota yang harus menyetujui dengan `checker`: maka hanya anggota tersebut yang dapat menyetujui atau menolak resolusi, dan kolom `checker` pada respons mencantumkan nama anggota tersebut. Tanpa `checker`, resolusi menunggu di antrean blueprint pemeriksa. Mengirim `checker` untuk blueprint tanpa langkah pemeriksa mengembalikan 400.",
        "operationId": "resolve_case",
        "x-didit-sdk": {
          "resource": "cases",
          "method": "resolve",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Cases"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID organisasi."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID aplikasi."
          },
          {
            "name": "case_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "c1a5e000-0000-4000-8000-000000000001"
            },
            "description": "UUID kasus."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "resolution"
                ],
                "properties": {
                  "resolution": {
                    "type": "string",
                    "enum": [
                      "FALSE_POSITIVE",
                      "VALID_THREAT",
                      "INCONCLUSIVE",
                      "REQUIREMENTS_NOT_MET",
                      "REQUIREMENTS_SATISFIED"
                    ]
                  },
                  "note": {
                    "type": "string",
                    "nullable": true,
                    "description": "Wajib jika blueprint menetapkan require_resolution_note."
                  },
                  "checker": {
                    "type": "string",
                    "format": "uuid",
                    "nullable": true,
                    "description": "Hanya untuk blueprint four-eyes. UUID pengguna dari anggota yang harus menyetujui resolusi ini (ID yang sama dengan `assigned_to.uuid` pada kasus, atau `members[].user_id` pada tim peninjau). Anggota harus memiliki akses kasus ke aplikasi ini dan tidak boleh merupakan petugas yang mengirimkan resolusi. Abaikan atau kirim null untuk membiarkan resolusi berada di antrean pemeriksa."
                  }
                }
              },
              "examples": {
                "Resolve": {
                  "value": {
                    "resolution": "FALSE_POSITIVE",
                    "note": "Confirmed legitimate activity after reviewing documents."
                  }
                },
                "Four-eyes blueprint with a named checker": {
                  "value": {
                    "resolution": "VALID_THREAT",
                    "note": "Document tampering confirmed.",
                    "checker": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/cases/c1a5e000-0000-4000-8000-000000000001/resolve/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"resolution\": \"FALSE_POSITIVE\", \"note\": \"Confirmed legitimate activity after reviewing documents.\"}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.resolve(\n    \"c1a5e000-0000-4000-8000-000000000001\",\n    resolution=\"FALSE_POSITIVE\",\n    note=\"Confirmed legitimate activity after reviewing documents.\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.resolve(\"c1a5e000-0000-4000-8000-000000000001\", {\n  resolution: \"FALSE_POSITIVE\",\n  note: \"Confirmed legitimate activity after reviewing documents.\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.Resolve(ctx, \"c1a5e000-0000-4000-8000-000000000001\", didit.CasesResolveParams{\n\tResolution: \"FALSE_POSITIVE\",\n\tNote:       didit.String(\"Confirmed legitimate activity after reviewing documents.\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.CasesResolveParams;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().resolve(\"c1a5e000-0000-4000-8000-000000000001\", CasesResolveParams.builder()\n        .resolution(CasesResolveParams.Resolution.of(\"FALSE_POSITIVE\"))\n        .note(\"Confirmed legitimate activity after reviewing documents.\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->cases->resolve('c1a5e000-0000-4000-8000-000000000001', [\n    'resolution' => 'FALSE_POSITIVE',\n    'note' => 'Confirmed legitimate activity after reviewing documents.',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.resolve(\n  \"c1a5e000-0000-4000-8000-000000000001\",\n  resolution: \"FALSE_POSITIVE\",\n  note: \"Confirmed legitimate activity after reviewing documents.\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.ResolveAsync(\"c1a5e000-0000-4000-8000-000000000001\", new CasesResolveParams\n{\n    Resolution = \"FALSE_POSITIVE\",\n    Note = \"Confirmed legitimate activity after reviewing documents.\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "Terselesaikan, atau ditangguhkan untuk persetujuan four-eyes.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CaseDetail"
                }
              }
            }
          },
          "400": {
            "description": "Penyelesaian ditolak. Kesalahan non-kolom diberikan sebagai daftar string: daftar periksa yang belum lengkap, catatan wajib yang hilang, atau `checker` yang tidak dapat diperiksa atau bukan merupakan peninjau aktif dengan akses kasus ke aplikasi ini. Kesalahan `checker` diberikan berdasarkan kolom: anggota yang disebutkan adalah petugas yang mengirimkan penyelesaian, atau cetak biru kasus tidak memiliki langkah pemeriksa.",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    {
                      "type": "object",
                      "additionalProperties": {
                        "type": "array",
                        "items": {
                          "type": "string"
                        }
                      }
                    }
                  ]
                },
                "examples": {
                  "Incomplete checklist": {
                    "value": [
                      "Case has incomplete checklist items: Verify source of funds"
                    ]
                  },
                  "Resolution note required": {
                    "value": [
                      "A resolution note is required to resolve this case."
                    ]
                  },
                  "Reviewer access could not be verified": {
                    "value": [
                      "Reviewer access could not be verified. Try again."
                    ]
                  },
                  "Checker is not an active reviewer": {
                    "value": [
                      "Choose an active reviewer with case access to this application."
                    ]
                  },
                  "Checker is the submitting officer": {
                    "value": {
                      "checker": [
                        "The officer who submitted the resolution cannot be its checker."
                      ]
                    }
                  },
                  "Policy has no checker step": {
                    "value": {
                      "checker": [
                        "This review policy has no checker step, so the case resolves directly."
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/cases/{case_uuid}/reopen/": {
      "post": {
        "summary": "Buka kembali kasus",
        "description": "Pindahkan kasus yang berstatus awaiting-user atau resolved kembali ke open, membersihkan resolution, resolution_notes, resolved_at, dan resolved_by_email.",
        "operationId": "reopen_case",
        "x-didit-sdk": {
          "resource": "cases",
          "method": "reopen",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Cases"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID organisasi."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID aplikasi."
          },
          {
            "name": "case_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "c1a5e000-0000-4000-8000-000000000001"
            },
            "description": "UUID kasus."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/cases/c1a5e000-0000-4000-8000-000000000001/reopen/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.reopen(\n    \"c1a5e000-0000-4000-8000-000000000001\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.reopen(\"c1a5e000-0000-4000-8000-000000000001\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.Reopen(ctx, \"c1a5e000-0000-4000-8000-000000000001\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().reopen(\"c1a5e000-0000-4000-8000-000000000001\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->cases->reopen('c1a5e000-0000-4000-8000-000000000001');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.reopen(\"c1a5e000-0000-4000-8000-000000000001\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.ReopenAsync(\"c1a5e000-0000-4000-8000-000000000001\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "Buka kembali kasus.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CaseDetail"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/cases/{case_uuid}/request-info/": {
      "post": {
        "summary": "Minta info (menunggu pengguna)",
        "description": "Pindahkan kasus yang open ke awaiting_user sementara informasi lebih lanjut dikumpulkan dari pengguna yang diverifikasi. Gagal dengan 400 jika resolusi saat ini sedang menunggu persetujuan 4-eyes.",
        "operationId": "request_case_info",
        "x-didit-sdk": {
          "resource": "cases",
          "method": "request_info",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Cases"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID organisasi."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID aplikasi."
          },
          {
            "name": "case_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "c1a5e000-0000-4000-8000-000000000001"
            },
            "description": "UUID kasus."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/cases/c1a5e000-0000-4000-8000-000000000001/request-info/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.request_info(\n    \"c1a5e000-0000-4000-8000-000000000001\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.requestInfo(\"c1a5e000-0000-4000-8000-000000000001\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.RequestInfo(ctx, \"c1a5e000-0000-4000-8000-000000000001\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().requestInfo(\"c1a5e000-0000-4000-8000-000000000001\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->cases->requestInfo('c1a5e000-0000-4000-8000-000000000001');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.request_info(\"c1a5e000-0000-4000-8000-000000000001\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.RequestInfoAsync(\"c1a5e000-0000-4000-8000-000000000001\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "Minta info (menunggu pengguna).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CaseDetail"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/cases/{case_uuid}/escalate/": {
      "post": {
        "summary": "Eskalasi kasus",
        "description": "Pindahkan kasus ke escalation_blueprint yang dikonfigurasi pada cetak birunya. Mengharuskan cetak biru saat ini memiliki escalation_enabled dan escalation_blueprint yang telah disetel, jika tidak, 400.",
        "operationId": "escalate_case",
        "x-didit-sdk": {
          "resource": "cases",
          "method": "escalate",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Cases"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID organisasi."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID aplikasi."
          },
          {
            "name": "case_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "c1a5e000-0000-4000-8000-000000000001"
            },
            "description": "UUID kasus."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/cases/c1a5e000-0000-4000-8000-000000000001/escalate/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.escalate(\n    \"c1a5e000-0000-4000-8000-000000000001\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.escalate(\"c1a5e000-0000-4000-8000-000000000001\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.Escalate(ctx, \"c1a5e000-0000-4000-8000-000000000001\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().escalate(\"c1a5e000-0000-4000-8000-000000000001\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->cases->escalate('c1a5e000-0000-4000-8000-000000000001');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.escalate(\"c1a5e000-0000-4000-8000-000000000001\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.EscalateAsync(\"c1a5e000-0000-4000-8000-000000000001\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "Eskalasi kasus.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CaseDetail"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/cases/{case_uuid}/transfer/": {
      "post": {
        "summary": "Transfer kasus",
        "description": "Pindahkan kasus ke cetak biru yang berbeda dan aktif dari aplikasi yang sama. Mengharuskan cetak biru saat ini memiliki transfer_enabled, jika tidak 400.",
        "operationId": "transfer_case",
        "x-didit-sdk": {
          "resource": "cases",
          "method": "transfer",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Cases"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID organisasi."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID aplikasi."
          },
          {
            "name": "case_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "c1a5e000-0000-4000-8000-000000000001"
            },
            "description": "UUID kasus."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "target_blueprint"
                ],
                "properties": {
                  "target_blueprint": {
                    "type": "string",
                    "format": "uuid"
                  }
                }
              },
              "example": {
                "target_blueprint": "b1de0000-0000-4000-8000-000000000002"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/cases/c1a5e000-0000-4000-8000-000000000001/transfer/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"target_blueprint\": \"b1de0000-0000-4000-8000-000000000002\"}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.transfer(\n    \"c1a5e000-0000-4000-8000-000000000001\",\n    target_blueprint=\"b1de0000-0000-4000-8000-000000000002\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.transfer(\"c1a5e000-0000-4000-8000-000000000001\", {\n  target_blueprint: \"b1de0000-0000-4000-8000-000000000002\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.Transfer(ctx, \"c1a5e000-0000-4000-8000-000000000001\", didit.CasesTransferParams{\n\tTargetBlueprint: \"b1de0000-0000-4000-8000-000000000002\",\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.CasesTransferParams;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().transfer(\"c1a5e000-0000-4000-8000-000000000001\", CasesTransferParams.builder()\n        .targetBlueprint(\"b1de0000-0000-4000-8000-000000000002\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->cases->transfer('c1a5e000-0000-4000-8000-000000000001', [\n    'target_blueprint' => 'b1de0000-0000-4000-8000-000000000002',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.transfer(\n  \"c1a5e000-0000-4000-8000-000000000001\",\n  target_blueprint: \"b1de0000-0000-4000-8000-000000000002\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.TransferAsync(\"c1a5e000-0000-4000-8000-000000000001\", new CasesTransferParams\n{\n    TargetBlueprint = \"b1de0000-0000-4000-8000-000000000002\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "Kasus ditransfer.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CaseDetail"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/cases/{case_uuid}/approve/": {
      "post": {
        "summary": "Setujui resolusi bertahap (4-eyes)",
        "description": "Terapkan resolusi yang disiapkan oleh resolve pada blueprint four-eyes. Pemanggil harus merupakan petugas yang berbeda dari yang mengirimkannya, jika tidak akan menghasilkan 403. Ketika resolusi menyebutkan checker (`checker` kasus), hanya anggota tersebut yang dapat menyetujuinya: pemanggil lain mana pun, termasuk kunci API, mendapatkan 403.",
        "operationId": "approve_case_resolution",
        "x-didit-sdk": {
          "resource": "cases",
          "method": "approve_resolution",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Cases"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID organisasi."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID aplikasi."
          },
          {
            "name": "case_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "c1a5e000-0000-4000-8000-000000000001"
            },
            "description": "UUID kasus."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/cases/c1a5e000-0000-4000-8000-000000000001/approve/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.approve_resolution(\n    \"c1a5e000-0000-4000-8000-000000000001\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.approveResolution(\"c1a5e000-0000-4000-8000-000000000001\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.ApproveResolution(ctx, \"c1a5e000-0000-4000-8000-000000000001\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().approveResolution(\"c1a5e000-0000-4000-8000-000000000001\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->cases->approveResolution('c1a5e000-0000-4000-8000-000000000001');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.approve_resolution(\"c1a5e000-0000-4000-8000-000000000001\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.ApproveResolutionAsync(\"c1a5e000-0000-4000-8000-000000000001\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "Resolusi diterapkan.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CaseDetail"
                }
              }
            }
          },
          "409": {
            "description": "Kasus tidak memiliki resolusi yang menunggu persetujuan.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Pemanggil tidak dapat menyetujui resolusi ini: mereka yang mengirimkannya, kasus tidak memiliki maker yang tercatat, atau resolusi menyebutkan checker yang berbeda. Kunci API selalu menerima 403 ini saat checker disebutkan.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Caller submitted the resolution": {
                    "value": {
                      "detail": "The officer who submitted the resolution cannot approve it."
                    }
                  },
                  "No recorded maker": {
                    "value": {
                      "detail": "Case has no recorded maker for this pending resolution; approve is not permitted."
                    }
                  },
                  "Caller is not the named checker": {
                    "value": {
                      "detail": "Only the named checker can approve this resolution."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/cases/{case_uuid}/reject-approval/": {
      "post": {
        "summary": "Tolak resolusi bertahap (prinsip 4 mata)",
        "description": "Tolak resolusi bertahap yang disiapkan oleh resolve dan kembalikan kasus ke blueprint pembuat. Pemanggil harus merupakan petugas yang berbeda dari yang mengirimkannya, jika tidak maka 403. Jika resolusi mencantumkan pemeriksa (`checker` kasus), hanya anggota tersebut yang dapat menolaknya: pemanggil lainnya, termasuk kunci API, akan mendapatkan 403.",
        "operationId": "reject_case_resolution",
        "x-didit-sdk": {
          "resource": "cases",
          "method": "reject_resolution",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Cases"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID organisasi."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID aplikasi."
          },
          {
            "name": "case_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "c1a5e000-0000-4000-8000-000000000001"
            },
            "description": "UUID kasus."
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "notes": {
                    "type": "string",
                    "nullable": true
                  }
                }
              },
              "example": {
                "notes": "Needs a clearer rationale before this can be approved."
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/cases/c1a5e000-0000-4000-8000-000000000001/reject-approval/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"notes\": \"Needs a clearer rationale before this can be approved.\"}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.reject_resolution(\n    \"c1a5e000-0000-4000-8000-000000000001\",\n    notes=\"Needs a clearer rationale before this can be approved.\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.rejectResolution(\"c1a5e000-0000-4000-8000-000000000001\", {\n  notes: \"Needs a clearer rationale before this can be approved.\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.RejectResolution(ctx, \"c1a5e000-0000-4000-8000-000000000001\", didit.CasesRejectResolutionParams{\n\tNotes: didit.String(\"Needs a clearer rationale before this can be approved.\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.CasesRejectResolutionParams;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().rejectResolution(\"c1a5e000-0000-4000-8000-000000000001\", CasesRejectResolutionParams.builder()\n        .notes(\"Needs a clearer rationale before this can be approved.\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->cases->rejectResolution('c1a5e000-0000-4000-8000-000000000001', [\n    'notes' => 'Needs a clearer rationale before this can be approved.',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.reject_resolution(\n  \"c1a5e000-0000-4000-8000-000000000001\",\n  notes: \"Needs a clearer rationale before this can be approved.\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.RejectResolutionAsync(\"c1a5e000-0000-4000-8000-000000000001\", new CasesRejectResolutionParams\n{\n    Notes = \"Needs a clearer rationale before this can be approved.\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "Resolusi ditolak, kasus dikembalikan ke blueprint pembuat.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CaseDetail"
                }
              }
            }
          },
          "409": {
            "description": "Kasus tidak memiliki resolusi yang menunggu persetujuan.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Pemanggil tidak dapat menolak resolusi ini: mereka yang mengirimkannya, kasus tidak memiliki maker yang tercatat, atau resolusi menyebutkan checker yang berbeda. Kunci API selalu menerima 403 ini saat checker disebutkan.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Caller submitted the resolution": {
                    "value": {
                      "detail": "The officer who submitted the resolution cannot reject it."
                    }
                  },
                  "No recorded maker": {
                    "value": {
                      "detail": "Case has no recorded maker for this pending resolution; reject is not permitted."
                    }
                  },
                  "Caller is not the named checker": {
                    "value": {
                      "detail": "Only the named checker can reject this resolution."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/cases/{case_uuid}/entity-actions/": {
      "post": {
        "operationId": "apply_case_entity_action",
        "x-didit-sdk": {
          "resource": "cases",
          "method": "apply_entity_action",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "parameters": [
          {
            "in": "path",
            "name": "organization_id",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          },
          {
            "in": "path",
            "name": "application_id",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          },
          {
            "in": "path",
            "name": "case_uuid",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          }
        ],
        "tags": [
          "Case Management"
        ],
        "requestBody": {
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/CaseActionCaseEntityActionRequest"
              }
            },
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CaseActionCaseEntityActionRequest"
              },
              "example": {
                "client_reference": "e1a00000-0000-4000-8000-000000000001",
                "action": "add_tags",
                "tags": [
                  "source-of-funds-reviewed"
                ]
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/CaseActionCaseEntityActionRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CaseActionCaseEntityActionResult"
                }
              }
            },
            "description": ""
          },
          "409": {
            "description": "Referensi ini milik payload tindakan yang berbeda."
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "description": "Terapkan satu tindakan eksplisit ke subjek kasus. Berikan client_reference unik untuk memperoleh tanda terima tindakan dan membuat percobaan ulang bersifat idempoten. Menggunakan kembali referensi tersebut dengan payload yang berbeda akan menghasilkan 409. Dengan referensi, periksa receipt.status meskipun status HTTP adalah 200: FAILED berarti tidak ada tindakan yang diterapkan. Mengulangi permintaan yang gagal tidak akan mengeksekusinya lagi kecuali retry bernilai true. Mengabaikan client_reference mempertahankan respons lama.",
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.apply_entity_action(\n    \"11111111-2222-3333-4444-555555555555\",\n    client_reference=\"e1a00000-0000-4000-8000-000000000001\",\n    action=\"add_tags\",\n    tags=[\"source-of-funds-reviewed\"],\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.applyEntityAction(\"11111111-2222-3333-4444-555555555555\", {\n  client_reference: \"e1a00000-0000-4000-8000-000000000001\",\n  action: \"add_tags\",\n  tags: [\"source-of-funds-reviewed\"],\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.ApplyEntityAction(ctx, \"11111111-2222-3333-4444-555555555555\", didit.CaseActionCaseEntityActionRequest{\n\tClientReference: didit.String(\"e1a00000-0000-4000-8000-000000000001\"),\n\tAction:          didit.CaseActionActionEnum(\"add_tags\"),\n\tTags:            didit.Some([]string{\"source-of-funds-reviewed\"}),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.List;\nimport me.didit.Didit;\nimport me.didit.types.CaseActionActionEnum;\nimport me.didit.types.CaseActionCaseEntityActionRequest;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().applyEntityAction(\"11111111-2222-3333-4444-555555555555\", CaseActionCaseEntityActionRequest.builder()\n        .clientReference(\"e1a00000-0000-4000-8000-000000000001\")\n        .action(CaseActionActionEnum.of(\"add_tags\"))\n        .tags(List.of(\"source-of-funds-reviewed\"))\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->cases->applyEntityAction('11111111-2222-3333-4444-555555555555', [\n    'client_reference' => 'e1a00000-0000-4000-8000-000000000001',\n    'action' => 'add_tags',\n    'tags' => ['source-of-funds-reviewed'],\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.apply_entity_action(\n  \"11111111-2222-3333-4444-555555555555\",\n  client_reference: \"e1a00000-0000-4000-8000-000000000001\",\n  action: \"add_tags\",\n  tags: [\"source-of-funds-reviewed\"]\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.ApplyEntityActionAsync(\"11111111-2222-3333-4444-555555555555\", new CaseActionCaseEntityActionRequest\n{\n    ClientReference = \"e1a00000-0000-4000-8000-000000000001\",\n    Action = \"add_tags\",\n    Tags = new string[] { \"source-of-funds-reviewed\" },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/cases/{case_uuid}/print/": {
      "get": {
        "summary": "Cetak kasus (PDF)",
        "description": "Render seluruh kasus (ringkasan, subjek, status daftar periksa, catatan, sesi/transaksi terlampir, event, daftar laporan FIU) sebagai PDF dan kembalikan URL unduhan yang telah ditandatangani sebelumnya (presigned).",
        "operationId": "print_case",
        "x-didit-sdk": {
          "resource": "cases",
          "method": "print",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Cases"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID organisasi."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID aplikasi."
          },
          {
            "name": "case_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "c1a5e000-0000-4000-8000-000000000001"
            },
            "description": "UUID kasus."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/cases/c1a5e000-0000-4000-8000-000000000001/print/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.print(\n    \"c1a5e000-0000-4000-8000-000000000001\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.print(\"c1a5e000-0000-4000-8000-000000000001\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.Print(ctx, \"c1a5e000-0000-4000-8000-000000000001\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().print(\"c1a5e000-0000-4000-8000-000000000001\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->cases->print('c1a5e000-0000-4000-8000-000000000001');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.print(\"c1a5e000-0000-4000-8000-000000000001\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.PrintAsync(\"c1a5e000-0000-4000-8000-000000000001\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "URL PDF presigned.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "url": {
                      "type": "string",
                      "format": "uri"
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/cases/{case_uuid}/notes/": {
      "get": {
        "operationId": "list_case_notes",
        "x-didit-sdk": {
          "resource": "cases.notes",
          "method": "list",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "parameters": [
          {
            "in": "path",
            "name": "organization_id",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          },
          {
            "in": "path",
            "name": "application_id",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          },
          {
            "in": "path",
            "name": "case_uuid",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          },
          {
            "name": "ordering",
            "required": false,
            "in": "query",
            "description": "Kolom mana yang digunakan saat mengurutkan hasil.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "description": "Jumlah hasil yang dikembalikan per halaman.",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "offset",
            "required": false,
            "in": "query",
            "description": "Indeks awal yang digunakan untuk mengembalikan hasil.",
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CaseCollaborationPaginatedCaseNoteList"
                }
              }
            },
            "description": ""
          },
          "403": {
            "description": "Pemanggil tidak memiliki izin kasus yang diperlukan."
          },
          "404": {
            "description": "Kasus atau catatan tidak tersedia untuk pemanggil ini."
          }
        },
        "tags": [
          "Case Management"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nfor item in client.cases.notes.list(\n    \"11111111-2222-3333-4444-555555555555\",\n):\n    print(item)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nfor await (const item of didit.cases.notes.list(\"11111111-2222-3333-4444-555555555555\")) {\n  console.log(item);\n}"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\niter := client.Cases.Notes.ListAutoPaging(ctx, \"11111111-2222-3333-4444-555555555555\", didit.CasesNotesListParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nfor (var item : client.cases().notes().list(\"11111111-2222-3333-4444-555555555555\")) {\n    System.out.println(item);\n}"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\nforeach ($didit->cases->notes->list('11111111-2222-3333-4444-555555555555') as $item) {\n    print_r($item->toArray());\n}"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\ndidit.cases.notes.list(\"11111111-2222-3333-4444-555555555555\").auto_paging_each do |item|\n  puts item.to_h\nend"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.Cases.Notes.ListAsync(\"11111111-2222-3333-4444-555555555555\"))\n{\n    Console.WriteLine(JsonSerializer.Serialize(item));\n}"
          }
        ]
      },
      "post": {
        "operationId": "create_case_note",
        "x-didit-sdk": {
          "resource": "cases.notes",
          "method": "create",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "parameters": [
          {
            "in": "path",
            "name": "organization_id",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          },
          {
            "in": "path",
            "name": "application_id",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          },
          {
            "in": "path",
            "name": "case_uuid",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          }
        ],
        "requestBody": {
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/CaseCollaborationCaseNoteCreateRequest"
              }
            },
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CaseCollaborationCaseNoteCreateRequest"
              },
              "example": {
                "comment": "Proof of address matches the ID document."
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/CaseCollaborationCaseNoteCreateRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CaseCollaborationCaseNote"
                }
              }
            },
            "description": ""
          },
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CaseCollaborationCaseNote"
                }
              }
            },
            "description": ""
          },
          "403": {
            "description": "Pemanggil tidak memiliki izin kasus yang diperlukan."
          },
          "404": {
            "description": "Kasus atau catatan tidak tersedia untuk pemanggil ini."
          },
          "409": {
            "description": "Referensi klien ini telah digunakan untuk catatan lain atau untuk catatan yang telah dihapus."
          }
        },
        "tags": [
          "Case Management"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "description": "Tambahkan catatan khusus untuk kasus ini. client_reference opsional memastikan bahwa coba lagi yang tidak mengalami perubahan akan mengembalikan catatan yang sama tanpa menduplikasi aktivitas atau notifikasi. reply_to harus mengidentifikasi catatan aktif dalam kasus ini. Respons menyertakan cuplikan induk terbatas tanpa menyalin cuplikan tersebut ke dalam balasan yang disimpan.",
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.notes.create(\n    \"11111111-2222-3333-4444-555555555555\",\n    comment=\"Proof of address matches the ID document.\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.notes.create(\"11111111-2222-3333-4444-555555555555\", {\n  comment: \"Proof of address matches the ID document.\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.Notes.Create(ctx, \"11111111-2222-3333-4444-555555555555\", didit.CaseCollaborationCaseNoteCreateRequest{\n\tComment: \"Proof of address matches the ID document.\",\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.CaseCollaborationCaseNoteCreateRequest;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().notes().create(\"11111111-2222-3333-4444-555555555555\", CaseCollaborationCaseNoteCreateRequest.builder()\n        .comment(\"Proof of address matches the ID document.\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->cases->notes->create('11111111-2222-3333-4444-555555555555', [\n    'comment' => 'Proof of address matches the ID document.',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.notes.create(\n  \"11111111-2222-3333-4444-555555555555\",\n  comment: \"Proof of address matches the ID document.\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.Notes.CreateAsync(\"11111111-2222-3333-4444-555555555555\", new CaseCollaborationCaseNoteCreateRequest\n{\n    Comment = \"Proof of address matches the ID document.\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/cases/{case_uuid}/notes/{note_uuid}/": {
      "patch": {
        "operationId": "root_partial_update",
        "x-didit-sdk": {
          "resource": "cases.notes",
          "method": "update",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "parameters": [
          {
            "in": "path",
            "name": "organization_id",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          },
          {
            "in": "path",
            "name": "application_id",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          },
          {
            "in": "path",
            "name": "case_uuid",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          },
          {
            "in": "path",
            "name": "note_uuid",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          }
        ],
        "requestBody": {
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/CaseCollaborationPatchedCaseNoteUpdateRequest"
              }
            },
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CaseCollaborationPatchedCaseNoteUpdateRequest"
              },
              "example": {
                "is_pinned": true
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/CaseCollaborationPatchedCaseNoteUpdateRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CaseCollaborationCaseNote"
                }
              }
            },
            "description": ""
          },
          "403": {
            "description": "Pemanggil tidak memiliki izin kasus yang diperlukan."
          },
          "404": {
            "description": "Kasus atau catatan tidak tersedia untuk pemanggil ini."
          }
        },
        "tags": [
          "Case Management"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "description": "Sematkan atau lepas sematan catatan yang sudah ada. Catatan yang disematkan muncul pertama. Perubahan penyematan dicatat dalam aktivitas kasus dan tidak mengubah bukti atau keputusan sumber.",
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.notes.update(\n    \"11111111-2222-3333-4444-555555555555\",\n    \"11111111-2222-3333-4444-555555555555\",\n    is_pinned=True,\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.notes.update(\n  \"11111111-2222-3333-4444-555555555555\",\n  \"11111111-2222-3333-4444-555555555555\",\n  {\n    is_pinned: true,\n  },\n);\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.Notes.Update(ctx, \"11111111-2222-3333-4444-555555555555\", \"11111111-2222-3333-4444-555555555555\", didit.CaseCollaborationPatchedCaseNoteUpdateRequest{\n\tIsPinned: didit.Bool(true),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.CaseCollaborationPatchedCaseNoteUpdateRequest;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().notes().update(\"11111111-2222-3333-4444-555555555555\", \"11111111-2222-3333-4444-555555555555\", CaseCollaborationPatchedCaseNoteUpdateRequest.builder()\n        .isPinned(true)\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->cases->notes->update('11111111-2222-3333-4444-555555555555', '11111111-2222-3333-4444-555555555555', [\n    'is_pinned' => true,\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.notes.update(\n  \"11111111-2222-3333-4444-555555555555\",\n  \"11111111-2222-3333-4444-555555555555\",\n  is_pinned: true\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.Notes.UpdateAsync(\"11111111-2222-3333-4444-555555555555\", \"11111111-2222-3333-4444-555555555555\", new CaseCollaborationPatchedCaseNoteUpdateRequest\n{\n    IsPinned = true,\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      },
      "delete": {
        "operationId": "delete_case_note",
        "x-didit-sdk": {
          "resource": "cases.notes",
          "method": "delete",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "parameters": [
          {
            "in": "path",
            "name": "organization_id",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          },
          {
            "in": "path",
            "name": "application_id",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          },
          {
            "in": "path",
            "name": "case_uuid",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          },
          {
            "in": "path",
            "name": "note_uuid",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          }
        ],
        "responses": {
          "204": {
            "description": "Catatan dihapus secara permanen. Balasan tetap ada, tanpa kutipan induk yang dihapus. Lampiran dihapus kecuali jika masih digunakan oleh catatan lain."
          },
          "403": {
            "description": "Pemanggil tidak memiliki izin kasus yang diperlukan."
          },
          "404": {
            "description": "Kasus atau catatan tidak tersedia untuk pemanggil ini."
          }
        },
        "tags": [
          "Case Management"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nclient.cases.notes.delete(\n    \"11111111-2222-3333-4444-555555555555\",\n    \"11111111-2222-3333-4444-555555555555\",\n)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nawait didit.cases.notes.delete(\n  \"11111111-2222-3333-4444-555555555555\",\n  \"11111111-2222-3333-4444-555555555555\",\n);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nif err := client.Cases.Notes.Delete(ctx, \"11111111-2222-3333-4444-555555555555\", \"11111111-2222-3333-4444-555555555555\"); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nclient.cases().notes().delete(\"11111111-2222-3333-4444-555555555555\", \"11111111-2222-3333-4444-555555555555\");"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$didit->cases->notes->delete('11111111-2222-3333-4444-555555555555', '11111111-2222-3333-4444-555555555555');"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\ndidit.cases.notes.delete(\n  \"11111111-2222-3333-4444-555555555555\",\n  \"11111111-2222-3333-4444-555555555555\"\n)"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nawait client.Cases.Notes.DeleteAsync(\"11111111-2222-3333-4444-555555555555\", \"11111111-2222-3333-4444-555555555555\");"
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/cases/{case_uuid}/notes/presign/": {
      "post": {
        "summary": "Unggah lampiran catatan",
        "description": "Unggah file (JPEG, PNG, WebP, PDF, teks biasa, atau CSV; maks 5 MB) untuk dilampirkan ke catatan. Mengembalikan s3_key untuk diteruskan dalam array lampiran pada catatan.",
        "operationId": "upload_case_note_attachment",
        "x-didit-sdk": {
          "resource": "cases.notes",
          "method": "create_attachment_upload",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Cases"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID organisasi."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID aplikasi."
          },
          {
            "name": "case_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "c1a5e000-0000-4000-8000-000000000001"
            },
            "description": "UUID kasus."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "required": [
                  "file"
                ],
                "properties": {
                  "file": {
                    "type": "string",
                    "format": "binary"
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/cases/c1a5e000-0000-4000-8000-000000000001/notes/presign/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -F 'file=@evidence.pdf'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.notes.create_attachment_upload(\n    \"c1a5e000-0000-4000-8000-000000000001\",\n    file=open(\"document.pdf\", \"rb\"),\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit, { fileFromPath } from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.notes.createAttachmentUpload(\"c1a5e000-0000-4000-8000-000000000001\", {\n  file: await fileFromPath(\"document.pdf\"),\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.Notes.CreateAttachmentUpload(ctx, \"c1a5e000-0000-4000-8000-000000000001\", didit.CasesNotesCreateAttachmentUploadParams{\n\tFile: didit.FileFromPath(\"document.pdf\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.nio.file.Path;\nimport me.didit.Didit;\nimport me.didit.types.CasesNotesCreateAttachmentUploadParams;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().notes().createAttachmentUpload(\"c1a5e000-0000-4000-8000-000000000001\", CasesNotesCreateAttachmentUploadParams.builder()\n        .file(Path.of(\"document.pdf\"))\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\nuse Didit\\File;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->cases->notes->createAttachmentUpload('c1a5e000-0000-4000-8000-000000000001', [\n    'file' => File::fromPath('document.pdf'),\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.notes.create_attachment_upload(\n  \"c1a5e000-0000-4000-8000-000000000001\",\n  file: Pathname(\"document.pdf\")\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.Notes.CreateAttachmentUploadAsync(\"c1a5e000-0000-4000-8000-000000000001\", new CasesNotesCreateAttachmentUploadParams\n{\n    File = FileUpload.FromPath(\"document.pdf\"),\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "201": {
            "description": "File diunggah.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "s3_key": {
                      "type": "string"
                    },
                    "url": {
                      "type": "string",
                      "format": "uri"
                    },
                    "filename": {
                      "type": "string"
                    },
                    "file_size": {
                      "type": "integer"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Tidak ada file, tipe konten tidak didukung, atau ukuran file melebihi 5 MB.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      },
      "get": {
        "summary": "Dapatkan URL lampiran catatan",
        "description": "Buat URL unduhan presigned baru untuk lampiran yang sudah tersimpan di salah satu catatan kasus.",
        "operationId": "get_case_note_attachment_url",
        "x-didit-sdk": {
          "resource": "cases.notes",
          "method": "retrieve_attachment_url",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Cases"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID organisasi."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID aplikasi."
          },
          {
            "name": "case_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "c1a5e000-0000-4000-8000-000000000001"
            },
            "description": "UUID kasus."
          },
          {
            "name": "s3_key",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "s3_key lampiran, seperti yang dikembalikan oleh unggahan atau tercantum pada catatan.",
            "required": true
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/cases/c1a5e000-0000-4000-8000-000000000001/notes/presign/?s3_key=case-notes/c1a5e000-0000-4000-8000-000000000001/evidence.pdf' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.notes.retrieve_attachment_url(\n    \"c1a5e000-0000-4000-8000-000000000001\",\n    s3_key=\"your-s3-key\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.notes.retrieveAttachmentUrl(\"c1a5e000-0000-4000-8000-000000000001\", {\n  s3_key: \"your-s3-key\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.Notes.RetrieveAttachmentURL(ctx, \"c1a5e000-0000-4000-8000-000000000001\", didit.CasesNotesRetrieveAttachmentURLParams{\n\tS3Key: \"your-s3-key\",\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.CasesNotesRetrieveAttachmentUrlParams;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().notes().retrieveAttachmentUrl(\"c1a5e000-0000-4000-8000-000000000001\", CasesNotesRetrieveAttachmentUrlParams.builder()\n        .s3Key(\"your-s3-key\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->cases->notes->retrieveAttachmentUrl('c1a5e000-0000-4000-8000-000000000001', [\n    's3_key' => 'your-s3-key',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.notes.retrieve_attachment_url(\n  \"c1a5e000-0000-4000-8000-000000000001\",\n  s3_key: \"your-s3-key\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.Notes.RetrieveAttachmentUrlAsync(\"c1a5e000-0000-4000-8000-000000000001\", new CasesNotesRetrieveAttachmentUrlParams\n{\n    S3Key = \"your-s3-key\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "URL presigned.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "s3_key": {
                      "type": "string"
                    },
                    "url": {
                      "type": "string",
                      "format": "uri"
                    },
                    "filename": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "s3_key tidak ada atau bukan milik kasus ini.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/cases/{case_uuid}/links/": {
      "get": {
        "summary": "Daftar tautan kasus",
        "description": "Mencantumkan daftar sesi, sesi bisnis, dan transaksi yang dilampirkan ke kasus.",
        "operationId": "list_case_links",
        "x-didit-sdk": {
          "resource": "cases.links",
          "method": "list",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Cases"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID organisasi."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID aplikasi."
          },
          {
            "name": "case_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "c1a5e000-0000-4000-8000-000000000001"
            },
            "description": "UUID kasus."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/cases/c1a5e000-0000-4000-8000-000000000001/links/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.links.list(\n    \"c1a5e000-0000-4000-8000-000000000001\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.links.list(\"c1a5e000-0000-4000-8000-000000000001\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.Links.List(ctx, \"c1a5e000-0000-4000-8000-000000000001\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().links().list(\"c1a5e000-0000-4000-8000-000000000001\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->cases->links->list('c1a5e000-0000-4000-8000-000000000001');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\ndidit.cases.links.list(\"c1a5e000-0000-4000-8000-000000000001\").each do |item|\n  puts item.to_h\nend"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.Links.ListAsync(\"c1a5e000-0000-4000-8000-000000000001\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "Tautan kasus.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/CaseLink"
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      },
      "post": {
        "summary": "Tambahkan tautan kasus",
        "description": "Lampirkan sesi, sesi bisnis, atau transaksi ke kasus. Ditolak dengan 400 jika entitas tersebut milik subjek yang berbeda dari kasus.",
        "operationId": "create_case_link",
        "x-didit-sdk": {
          "resource": "cases.links",
          "method": "create",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Cases"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID organisasi."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID aplikasi."
          },
          {
            "name": "case_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "c1a5e000-0000-4000-8000-000000000001"
            },
            "description": "UUID kasus."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "entity_type",
                  "entity_uuid"
                ],
                "properties": {
                  "entity_type": {
                    "type": "string",
                    "enum": [
                      "session",
                      "business_session",
                      "transaction"
                    ]
                  },
                  "entity_uuid": {
                    "type": "string",
                    "format": "uuid"
                  }
                }
              },
              "example": {
                "entity_type": "transaction",
                "entity_uuid": "77000000-0000-4000-8000-000000000077"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/cases/c1a5e000-0000-4000-8000-000000000001/links/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"entity_type\": \"transaction\", \"entity_uuid\": \"77000000-0000-4000-8000-000000000077\"}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.links.create(\n    \"c1a5e000-0000-4000-8000-000000000001\",\n    entity_type=\"transaction\",\n    entity_uuid=\"77000000-0000-4000-8000-000000000077\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.links.create(\"c1a5e000-0000-4000-8000-000000000001\", {\n  entity_type: \"transaction\",\n  entity_uuid: \"77000000-0000-4000-8000-000000000077\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.Links.Create(ctx, \"c1a5e000-0000-4000-8000-000000000001\", didit.CasesLinksCreateParams{\n\tEntityType: \"transaction\",\n\tEntityUUID: \"77000000-0000-4000-8000-000000000077\",\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.CasesLinksCreateParams;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().links().create(\"c1a5e000-0000-4000-8000-000000000001\", CasesLinksCreateParams.builder()\n        .entityType(CasesLinksCreateParams.EntityType.of(\"transaction\"))\n        .entityUuid(\"77000000-0000-4000-8000-000000000077\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->cases->links->create('c1a5e000-0000-4000-8000-000000000001', [\n    'entity_type' => 'transaction',\n    'entity_uuid' => '77000000-0000-4000-8000-000000000077',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.links.create(\n  \"c1a5e000-0000-4000-8000-000000000001\",\n  entity_type: \"transaction\",\n  entity_uuid: \"77000000-0000-4000-8000-000000000077\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.Links.CreateAsync(\"c1a5e000-0000-4000-8000-000000000001\", new CasesLinksCreateParams\n{\n    EntityType = \"transaction\",\n    EntityUuid = \"77000000-0000-4000-8000-000000000077\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "201": {
            "description": "Tautan dibuat.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CaseLink"
                }
              }
            }
          },
          "400": {
            "description": "Entitas milik profil yang berbeda dari subjek kasus.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/cases/{case_uuid}/links/{link_uuid}/": {
      "delete": {
        "summary": "Hapus tautan kasus",
        "description": "Lepaskan tautan sesi, sesi bisnis, atau transaksi dari kasus.",
        "operationId": "delete_case_link",
        "x-didit-sdk": {
          "resource": "cases.links",
          "method": "delete",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Cases"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID organisasi."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID aplikasi."
          },
          {
            "name": "case_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "c1a5e000-0000-4000-8000-000000000001"
            },
            "description": "UUID kasus."
          },
          {
            "name": "link_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "11000000-0000-4000-8000-000000000004"
            },
            "description": "UUID tautan."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X DELETE 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/cases/c1a5e000-0000-4000-8000-000000000001/links/11000000-0000-4000-8000-000000000004/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nclient.cases.links.delete(\n    \"c1a5e000-0000-4000-8000-000000000001\",\n    \"11000000-0000-4000-8000-000000000004\",\n)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nawait didit.cases.links.delete(\n  \"c1a5e000-0000-4000-8000-000000000001\",\n  \"11000000-0000-4000-8000-000000000004\",\n);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nif err := client.Cases.Links.Delete(ctx, \"c1a5e000-0000-4000-8000-000000000001\", \"11000000-0000-4000-8000-000000000004\"); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nclient.cases().links().delete(\"c1a5e000-0000-4000-8000-000000000001\", \"11000000-0000-4000-8000-000000000004\");"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$didit->cases->links->delete('c1a5e000-0000-4000-8000-000000000001', '11000000-0000-4000-8000-000000000004');"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\ndidit.cases.links.delete(\n  \"c1a5e000-0000-4000-8000-000000000001\",\n  \"11000000-0000-4000-8000-000000000004\"\n)"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nawait client.Cases.Links.DeleteAsync(\"c1a5e000-0000-4000-8000-000000000001\", \"11000000-0000-4000-8000-000000000004\");"
          }
        ],
        "responses": {
          "204": {
            "description": "Tautan dihapus."
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/cases/{case_uuid}/events/": {
      "get": {
        "summary": "Daftar event kasus",
        "description": "Lini masa audit kasus bersifat hanya-baca (dibuat, perubahan status, penugasan, penyelesaian, eskalasi, transfer, perubahan tag/prioritas/tenggat waktu, tindakan entitas, dan banyak lagi).",
        "operationId": "list_case_events",
        "x-didit-sdk": {
          "resource": "cases",
          "method": "list_events",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Cases"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID organisasi."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID aplikasi."
          },
          {
            "name": "case_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "c1a5e000-0000-4000-8000-000000000001"
            },
            "description": "UUID kasus."
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 50,
              "minimum": 1
            },
            "description": "Ukuran halaman."
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 0,
              "minimum": 0
            },
            "description": "Offset berbasis nol."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/cases/c1a5e000-0000-4000-8000-000000000001/events/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nfor item in client.cases.list_events(\n    \"c1a5e000-0000-4000-8000-000000000001\",\n):\n    print(item)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nfor await (const item of didit.cases.listEvents(\"c1a5e000-0000-4000-8000-000000000001\")) {\n  console.log(item);\n}"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\niter := client.Cases.ListEventsAutoPaging(ctx, \"c1a5e000-0000-4000-8000-000000000001\", didit.CasesListEventsParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nfor (var item : client.cases().listEvents(\"c1a5e000-0000-4000-8000-000000000001\")) {\n    System.out.println(item);\n}"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\nforeach ($didit->cases->listEvents('c1a5e000-0000-4000-8000-000000000001') as $item) {\n    print_r($item->toArray());\n}"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\ndidit.cases.list_events(\"c1a5e000-0000-4000-8000-000000000001\").auto_paging_each do |item|\n  puts item.to_h\nend"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.Cases.ListEventsAsync(\"c1a5e000-0000-4000-8000-000000000001\"))\n{\n    Console.WriteLine(JsonSerializer.Serialize(item));\n}"
          }
        ],
        "responses": {
          "200": {
            "description": "Event berpaginasi, terbaru terlebih dahulu.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "count": {
                      "type": "integer",
                      "description": "Jumlah baris yang cocok. Tepat hingga 100, dibatasi maksimal 100 setelahnya demi performa. Andalkan nilai `next` yang null untuk mendeteksi halaman terakhir."
                    },
                    "next": {
                      "type": "string",
                      "nullable": true,
                      "description": "URL absolut halaman berikutnya, atau null."
                    },
                    "previous": {
                      "type": "string",
                      "nullable": true,
                      "description": "URL absolut halaman sebelumnya, atau null."
                    },
                    "results": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/CaseEvent"
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/cases/{case_uuid}/checklist/": {
      "get": {
        "summary": "Daftar checklist kasus",
        "description": "Mencantumkan daftar item daftar periksa kasus, yang disalin dari content_config.checklist.items milik cetak biru saat pembuatan, berurutan.",
        "operationId": "list_case_checklist",
        "x-didit-sdk": {
          "resource": "cases.checklist",
          "method": "list",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Cases"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID organisasi."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID aplikasi."
          },
          {
            "name": "case_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "c1a5e000-0000-4000-8000-000000000001"
            },
            "description": "UUID kasus."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/cases/c1a5e000-0000-4000-8000-000000000001/checklist/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.checklist.list(\n    \"c1a5e000-0000-4000-8000-000000000001\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.checklist.list(\"c1a5e000-0000-4000-8000-000000000001\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.Checklist.List(ctx, \"c1a5e000-0000-4000-8000-000000000001\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().checklist().list(\"c1a5e000-0000-4000-8000-000000000001\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->cases->checklist->list('c1a5e000-0000-4000-8000-000000000001');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\ndidit.cases.checklist.list(\"c1a5e000-0000-4000-8000-000000000001\").each do |item|\n  puts item.to_h\nend"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.Checklist.ListAsync(\"c1a5e000-0000-4000-8000-000000000001\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "Item daftar periksa.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/CaseChecklistItem"
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/cases/{case_uuid}/checklist/{item_uuid}/": {
      "patch": {
        "summary": "Aktifkan/nonaktifkan item daftar periksa",
        "description": "Tandai item daftar periksa sebagai selesai atau belum selesai. Penyelesaian diblokir selama ada item yang belum selesai, kecuali blueprint menandai daftar periksa tersebut sebagai opsional.",
        "operationId": "toggle_case_checklist_item",
        "x-didit-sdk": {
          "resource": "cases.checklist",
          "method": "toggle_item",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Cases"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID organisasi."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID aplikasi."
          },
          {
            "name": "case_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "c1a5e000-0000-4000-8000-000000000001"
            },
            "description": "UUID kasus."
          },
          {
            "name": "item_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "c4ec0000-0000-4000-8000-000000000005"
            },
            "description": "UUID item daftar periksa."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "is_completed"
                ],
                "properties": {
                  "is_completed": {
                    "type": "boolean"
                  }
                }
              },
              "example": {
                "is_completed": true
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X PATCH 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/cases/c1a5e000-0000-4000-8000-000000000001/checklist/c4ec0000-0000-4000-8000-000000000005/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"is_completed\": true}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.checklist.toggle_item(\n    \"c1a5e000-0000-4000-8000-000000000001\",\n    \"c4ec0000-0000-4000-8000-000000000005\",\n    is_completed=True,\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.checklist.toggleItem(\n  \"c1a5e000-0000-4000-8000-000000000001\",\n  \"c4ec0000-0000-4000-8000-000000000005\",\n  {\n    is_completed: true,\n  },\n);\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.Checklist.ToggleItem(ctx, \"c1a5e000-0000-4000-8000-000000000001\", \"c4ec0000-0000-4000-8000-000000000005\", didit.CasesChecklistToggleItemParams{\n\tIsCompleted: true,\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.CasesChecklistToggleItemParams;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().checklist().toggleItem(\"c1a5e000-0000-4000-8000-000000000001\", \"c4ec0000-0000-4000-8000-000000000005\", CasesChecklistToggleItemParams.builder()\n        .isCompleted(true)\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->cases->checklist->toggleItem('c1a5e000-0000-4000-8000-000000000001', 'c4ec0000-0000-4000-8000-000000000005', [\n    'is_completed' => true,\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.checklist.toggle_item(\n  \"c1a5e000-0000-4000-8000-000000000001\",\n  \"c4ec0000-0000-4000-8000-000000000005\",\n  is_completed: true\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.Checklist.ToggleItemAsync(\"c1a5e000-0000-4000-8000-000000000001\", \"c4ec0000-0000-4000-8000-000000000005\", new CasesChecklistToggleItemParams\n{\n    IsCompleted = true,\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "Item daftar periksa yang diperbarui.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CaseChecklistItem"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/cases/{case_uuid}/aml/": {
      "get": {
        "summary": "Daftar hit AML pada kasus",
        "description": "Daftar hasil skrining AML untuk subjek kasus. Bentuk yang sama seperti hasil yang dikembalikan oleh POST /v3/aml/.",
        "operationId": "list_case_aml_hits",
        "x-didit-sdk": {
          "resource": "cases",
          "method": "list_aml_hits",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Cases"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID organisasi."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID aplikasi."
          },
          {
            "name": "case_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "c1a5e000-0000-4000-8000-000000000001"
            },
            "description": "UUID kasus."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/cases/c1a5e000-0000-4000-8000-000000000001/aml/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.list_aml_hits(\n    \"c1a5e000-0000-4000-8000-000000000001\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.listAmlHits(\"c1a5e000-0000-4000-8000-000000000001\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.ListAMLHits(ctx, \"c1a5e000-0000-4000-8000-000000000001\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().listAmlHits(\"c1a5e000-0000-4000-8000-000000000001\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->cases->listAmlHits('c1a5e000-0000-4000-8000-000000000001');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\ndidit.cases.list_aml_hits(\"c1a5e000-0000-4000-8000-000000000001\").each do |item|\n  puts item.to_h\nend"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.ListAmlHitsAsync(\"c1a5e000-0000-4000-8000-000000000001\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "Hasil temuan AML.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/AMLScreening"
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/cases/statistics/": {
      "get": {
        "summary": "Analitik kasus",
        "description": "Analitik kasus agregat untuk rentang tanggal (default ke 30 hari terakhir; maks 731 hari). Bagan, tabel, total, event penugasan, dan hitungan antrean saat ini menggunakan filter dengan cakupan aplikasi yang sama. Filter menggunakan nilai kasus saat ini. Tanggal berlaku untuk setiap event metrik, sehingga kasus lama yang ditugaskan atau diselesaikan selama periode tersebut tetap disertakan. Kedalaman antrean bersifat independen dari rentang tanggal. Filter yang tidak valid mengembalikan 400; blueprint atau penerima tugas yang tidak diketahui mengembalikan hasil kosong.",
        "operationId": "get_case_analytics",
        "x-didit-sdk": {
          "resource": "cases",
          "method": "retrieve_statistics",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Cases"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID organisasi."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID aplikasi."
          },
          {
            "name": "date_from",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date"
            },
            "description": "Awal rentang (inklusif). Defaultnya adalah 30 hari yang lalu."
          },
          {
            "name": "date_to",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date"
            },
            "description": "Akhir rentang (inklusif). Defaultnya adalah hari ini."
          },
          {
            "name": "blueprint",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Filter berdasarkan UUID cetak biru saat ini."
          },
          {
            "name": "assigned_to",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Filter berdasarkan UUID pengguna peninjau yang saat ini ditugaskan."
          },
          {
            "name": "priority",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "LOW",
                "MEDIUM",
                "HIGH"
              ]
            },
            "description": "Filter berdasarkan prioritas kasus saat ini."
          },
          {
            "name": "source",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "MANUAL",
                "AML_SCREENING",
                "TRANSACTION_RULE",
                "WORKFLOW_BUILDER"
              ]
            },
            "description": "Filter berdasarkan sumber pembuatan kasus."
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "OPEN",
                "AWAITING_USER",
                "RESOLVED"
              ]
            },
            "description": "Filter berdasarkan status kasus saat ini."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/cases/statistics/?date_from=2026-06-01&date_to=2026-06-30' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.retrieve_statistics()\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.retrieveStatistics();\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.RetrieveStatistics(ctx, didit.CasesRetrieveStatisticsParams{})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().retrieveStatistics();\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->cases->retrieveStatistics();\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.retrieve_statistics\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.RetrieveStatisticsAsync();\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "Payload analitik.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "series": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "date": {
                            "type": "string",
                            "format": "date"
                          },
                          "created": {
                            "type": "integer"
                          },
                          "reviewed": {
                            "type": "integer"
                          }
                        }
                      }
                    },
                    "tables": {
                      "type": "object",
                      "properties": {
                        "officer": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "key": {
                                "type": "string",
                                "description": "Nilai dimensi: email petugas, \"blueprint_name:uuid\", sumber, atau status. \"unassigned\"/\"none\" untuk dimensi yang tidak ada."
                              },
                              "created": {
                                "type": "integer"
                              },
                              "assigned": {
                                "type": "integer"
                              },
                              "resolved": {
                                "type": "integer"
                              },
                              "threat_rate": {
                                "type": "number",
                                "format": "float"
                              },
                              "false_positive_rate": {
                                "type": "number",
                                "format": "float"
                              },
                              "unresolved": {
                                "type": "integer"
                              },
                              "reassignment_rate": {
                                "type": "number",
                                "format": "float"
                              },
                              "escalation_rate": {
                                "type": "number",
                                "format": "float"
                              },
                              "avg_assign_hours": {
                                "type": "number",
                                "format": "float"
                              },
                              "avg_resolve_hours": {
                                "type": "number",
                                "format": "float"
                              },
                              "avg_handling_hours": {
                                "type": "number",
                                "format": "float"
                              }
                            }
                          }
                        },
                        "blueprint": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "key": {
                                "type": "string",
                                "description": "Nilai dimensi: email petugas, \"blueprint_name:uuid\", sumber, atau status. \"unassigned\"/\"none\" untuk dimensi yang tidak ada."
                              },
                              "created": {
                                "type": "integer"
                              },
                              "assigned": {
                                "type": "integer"
                              },
                              "resolved": {
                                "type": "integer"
                              },
                              "threat_rate": {
                                "type": "number",
                                "format": "float"
                              },
                              "false_positive_rate": {
                                "type": "number",
                                "format": "float"
                              },
                              "unresolved": {
                                "type": "integer"
                              },
                              "reassignment_rate": {
                                "type": "number",
                                "format": "float"
                              },
                              "escalation_rate": {
                                "type": "number",
                                "format": "float"
                              },
                              "avg_assign_hours": {
                                "type": "number",
                                "format": "float"
                              },
                              "avg_resolve_hours": {
                                "type": "number",
                                "format": "float"
                              },
                              "avg_handling_hours": {
                                "type": "number",
                                "format": "float"
                              }
                            }
                          }
                        },
                        "source": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "key": {
                                "type": "string",
                                "description": "Nilai dimensi: email petugas, \"blueprint_name:uuid\", sumber, atau status. \"unassigned\"/\"none\" untuk dimensi yang tidak ada."
                              },
                              "created": {
                                "type": "integer"
                              },
                              "assigned": {
                                "type": "integer"
                              },
                              "resolved": {
                                "type": "integer"
                              },
                              "threat_rate": {
                                "type": "number",
                                "format": "float"
                              },
                              "false_positive_rate": {
                                "type": "number",
                                "format": "float"
                              },
                              "unresolved": {
                                "type": "integer"
                              },
                              "reassignment_rate": {
                                "type": "number",
                                "format": "float"
                              },
                              "escalation_rate": {
                                "type": "number",
                                "format": "float"
                              },
                              "avg_assign_hours": {
                                "type": "number",
                                "format": "float"
                              },
                              "avg_resolve_hours": {
                                "type": "number",
                                "format": "float"
                              },
                              "avg_handling_hours": {
                                "type": "number",
                                "format": "float"
                              }
                            }
                          }
                        },
                        "status": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "key": {
                                "type": "string",
                                "description": "Nilai dimensi: email petugas, \"blueprint_name:uuid\", sumber, atau status. \"unassigned\"/\"none\" untuk dimensi yang tidak ada."
                              },
                              "created": {
                                "type": "integer"
                              },
                              "assigned": {
                                "type": "integer"
                              },
                              "resolved": {
                                "type": "integer"
                              },
                              "threat_rate": {
                                "type": "number",
                                "format": "float"
                              },
                              "false_positive_rate": {
                                "type": "number",
                                "format": "float"
                              },
                              "unresolved": {
                                "type": "integer"
                              },
                              "reassignment_rate": {
                                "type": "number",
                                "format": "float"
                              },
                              "escalation_rate": {
                                "type": "number",
                                "format": "float"
                              },
                              "avg_assign_hours": {
                                "type": "number",
                                "format": "float"
                              },
                              "avg_resolve_hours": {
                                "type": "number",
                                "format": "float"
                              },
                              "avg_handling_hours": {
                                "type": "number",
                                "format": "float"
                              }
                            }
                          }
                        }
                      }
                    },
                    "totals": {
                      "type": "object",
                      "properties": {
                        "created": {
                          "type": "integer"
                        },
                        "assigned": {
                          "type": "integer"
                        },
                        "resolved": {
                          "type": "integer"
                        },
                        "threat_rate": {
                          "type": "number",
                          "format": "float"
                        },
                        "false_positive_rate": {
                          "type": "number",
                          "format": "float"
                        },
                        "unresolved": {
                          "type": "integer"
                        },
                        "reassignment_rate": {
                          "type": "number",
                          "format": "float"
                        },
                        "escalation_rate": {
                          "type": "number",
                          "format": "float"
                        },
                        "avg_assign_hours": {
                          "type": "number",
                          "format": "float"
                        },
                        "avg_resolve_hours": {
                          "type": "number",
                          "format": "float"
                        },
                        "avg_handling_hours": {
                          "type": "number",
                          "format": "float"
                        }
                      }
                    },
                    "queue": {
                      "type": "object",
                      "description": "Cuplikan langsung, tidak dicakup ke rentang tanggal.",
                      "properties": {
                        "open": {
                          "type": "integer"
                        },
                        "overdue": {
                          "type": "integer"
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/cases/bulk/status/": {
      "post": {
        "summary": "Pembaruan massal status kasus",
        "description": "Terapkan transisi status yang sama ke beberapa kasus dalam satu panggilan: OPEN membuka kembali, AWAITING_USER meminta info, RESOLVED menyelesaikan (resolusi diperlukan). Setiap kasus dievaluasi secara independen; kegagalan pemeriksaan (daftar periksa tidak lengkap, catatan wajib tidak ada) dilaporkan per kasus tanpa membatalkan batch.",
        "operationId": "bulk_update_case_status",
        "x-didit-sdk": {
          "resource": "cases",
          "method": "bulk_update_status",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Cases"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID organisasi."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID aplikasi."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "case_uuids",
                  "status"
                ],
                "properties": {
                  "case_uuids": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "minItems": 1
                  },
                  "status": {
                    "type": "string",
                    "enum": [
                      "OPEN",
                      "AWAITING_USER",
                      "RESOLVED"
                    ]
                  },
                  "resolution": {
                    "type": "string",
                    "enum": [
                      "FALSE_POSITIVE",
                      "VALID_THREAT",
                      "INCONCLUSIVE",
                      "REQUIREMENTS_NOT_MET",
                      "REQUIREMENTS_SATISFIED"
                    ],
                    "description": "Wajib jika status adalah RESOLVED."
                  },
                  "note": {
                    "type": "string",
                    "nullable": true
                  }
                }
              },
              "example": {
                "case_uuids": [
                  "c1a5e000-0000-4000-8000-000000000001"
                ],
                "status": "RESOLVED",
                "resolution": "FALSE_POSITIVE"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/cases/bulk/status/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"case_uuids\": [\"c1a5e000-0000-4000-8000-000000000001\"], \"status\": \"RESOLVED\", \"resolution\": \"FALSE_POSITIVE\"}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.bulk_update_status(\n    case_uuids=[\"c1a5e000-0000-4000-8000-000000000001\"],\n    status=\"RESOLVED\",\n    resolution=\"FALSE_POSITIVE\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.bulkUpdateStatus({\n  case_uuids: [\"c1a5e000-0000-4000-8000-000000000001\"],\n  status: \"RESOLVED\",\n  resolution: \"FALSE_POSITIVE\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.BulkUpdateStatus(ctx, didit.CasesBulkUpdateStatusParams{\n\tCaseUUIDs:  []string{\"c1a5e000-0000-4000-8000-000000000001\"},\n\tStatus:     \"RESOLVED\",\n\tResolution: didit.Some(didit.CasesBulkUpdateStatusParamsResolution(\"FALSE_POSITIVE\")),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.List;\nimport me.didit.Didit;\nimport me.didit.types.CasesBulkUpdateStatusParams;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().bulkUpdateStatus(CasesBulkUpdateStatusParams.builder()\n        .caseUuids(List.of(\"c1a5e000-0000-4000-8000-000000000001\"))\n        .status(CasesBulkUpdateStatusParams.Status.of(\"RESOLVED\"))\n        .resolution(CasesBulkUpdateStatusParams.Resolution.of(\"FALSE_POSITIVE\"))\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->cases->bulkUpdateStatus([\n    'case_uuids' => ['c1a5e000-0000-4000-8000-000000000001'],\n    'status' => 'RESOLVED',\n    'resolution' => 'FALSE_POSITIVE',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.bulk_update_status(\n  case_uuids: [\"c1a5e000-0000-4000-8000-000000000001\"],\n  status: \"RESOLVED\",\n  resolution: \"FALSE_POSITIVE\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.BulkUpdateStatusAsync(new CasesBulkUpdateStatusParams\n{\n    CaseUuids = new string[] { \"c1a5e000-0000-4000-8000-000000000001\" },\n    Status = \"RESOLVED\",\n    Resolution = new CasesBulkUpdateStatusParamsResolution(\"FALSE_POSITIVE\"),\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "Hasil per kasus.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CaseBulkUpdateResult"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/cases/bulk/assign/": {
      "post": {
        "summary": "Tetapkan kasus secara massal",
        "description": "Tetapkan (atau batalkan penetapan, dengan assignee_user_id: null) beberapa kasus sekaligus. Semua kasus harus menggunakan blueprint yang sama; ketidakcocokan dilaporkan per kasus tanpa membatalkan batch.",
        "operationId": "bulk_assign_cases",
        "x-didit-sdk": {
          "resource": "cases",
          "method": "bulk_assign",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Cases"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID organisasi."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID aplikasi."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "case_uuids",
                  "assignee_user_id"
                ],
                "properties": {
                  "case_uuids": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "minItems": 1
                  },
                  "assignee_user_id": {
                    "type": "string",
                    "format": "uuid",
                    "nullable": true
                  },
                  "assignee_email": {
                    "type": "string",
                    "format": "email",
                    "nullable": true
                  },
                  "assignee_name": {
                    "type": "string",
                    "nullable": true
                  }
                }
              },
              "example": {
                "case_uuids": [
                  "c1a5e000-0000-4000-8000-000000000001"
                ],
                "assignee_user_id": "9a000000-0000-4000-8000-0000000000aa"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/cases/bulk/assign/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"case_uuids\": [\"c1a5e000-0000-4000-8000-000000000001\"], \"assignee_user_id\": \"9a000000-0000-4000-8000-0000000000aa\"}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.bulk_assign(\n    case_uuids=[\"c1a5e000-0000-4000-8000-000000000001\"],\n    assignee_user_id=\"9a000000-0000-4000-8000-0000000000aa\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.bulkAssign({\n  case_uuids: [\"c1a5e000-0000-4000-8000-000000000001\"],\n  assignee_user_id: \"9a000000-0000-4000-8000-0000000000aa\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.BulkAssign(ctx, didit.CasesBulkAssignParams{\n\tCaseUUIDs:      []string{\"c1a5e000-0000-4000-8000-000000000001\"},\n\tAssigneeUserID: didit.String(\"9a000000-0000-4000-8000-0000000000aa\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.List;\nimport me.didit.Didit;\nimport me.didit.types.CasesBulkAssignParams;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().bulkAssign(CasesBulkAssignParams.builder()\n        .caseUuids(List.of(\"c1a5e000-0000-4000-8000-000000000001\"))\n        .assigneeUserId(\"9a000000-0000-4000-8000-0000000000aa\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->cases->bulkAssign([\n    'case_uuids' => ['c1a5e000-0000-4000-8000-000000000001'],\n    'assignee_user_id' => '9a000000-0000-4000-8000-0000000000aa',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.bulk_assign(\n  case_uuids: [\"c1a5e000-0000-4000-8000-000000000001\"],\n  assignee_user_id: \"9a000000-0000-4000-8000-0000000000aa\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.BulkAssignAsync(new CasesBulkAssignParams\n{\n    CaseUuids = new string[] { \"c1a5e000-0000-4000-8000-000000000001\" },\n    AssigneeUserId = \"9a000000-0000-4000-8000-0000000000aa\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "Hasil per kasus.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CaseBulkUpdateResult"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/cases/blueprints/": {
      "get": {
        "summary": "Daftar blueprint",
        "description": "Daftar blueprint kasus untuk aplikasi.",
        "operationId": "list_case_blueprints",
        "x-didit-sdk": {
          "resource": "cases.blueprints",
          "method": "list",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Case Blueprints"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID organisasi."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID aplikasi."
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 50,
              "minimum": 1
            },
            "description": "Ukuran halaman."
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 0,
              "minimum": 0
            },
            "description": "Offset berbasis nol."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/cases/blueprints/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nfor item in client.cases.blueprints.list():\n    print(item)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nfor await (const item of didit.cases.blueprints.list()) {\n  console.log(item);\n}"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\niter := client.Cases.Blueprints.ListAutoPaging(ctx, didit.CasesBlueprintsListParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nfor (var item : client.cases().blueprints().list()) {\n    System.out.println(item);\n}"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\nforeach ($didit->cases->blueprints->list() as $item) {\n    print_r($item->toArray());\n}"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\ndidit.cases.blueprints.list.auto_paging_each do |item|\n  puts item.to_h\nend"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.Cases.Blueprints.ListAsync())\n{\n    Console.WriteLine(JsonSerializer.Serialize(item));\n}"
          }
        ],
        "responses": {
          "200": {
            "description": "Daftar blueprint berpaginasi.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "count": {
                      "type": "integer",
                      "description": "Jumlah baris yang cocok, dibatasi pada 100 demi performa."
                    },
                    "next": {
                      "type": "string",
                      "nullable": true
                    },
                    "previous": {
                      "type": "string",
                      "nullable": true
                    },
                    "results": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/CaseBlueprintListItem"
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      },
      "post": {
        "summary": "Buat blueprint",
        "description": "Buat blueprint kasus: pengaturan umum (penugasan, eskalasi, transfer, pemasangan empat mata) ditambah content_config, enam bagian yang menentukan halaman kasus. Atur publish=false untuk membuat draf yang belum dipublikasikan; Publish membuat versi aktif pertamanya. Membuang draf yang belum pernah dipublikasikan akan menghapusnya.",
        "operationId": "create_case_blueprint",
        "x-didit-sdk": {
          "resource": "cases.blueprints",
          "method": "create",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Case Blueprints"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID organisasi."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID aplikasi."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "name",
                  "assignee_pool"
                ],
                "properties": {
                  "name": {
                    "type": "string",
                    "maxLength": 24,
                    "description": "Maksimal 24 karakter, misalnya \"investigasi AML\"."
                  },
                  "description": {
                    "type": "string",
                    "nullable": true
                  },
                  "assignee_pool": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "minItems": 1,
                    "description": "Daftar UUID Pengguna. Array kosong ditolak dengan \"Pilih setidaknya satu penerima tugas\"."
                  },
                  "assignment_method": {
                    "type": "string",
                    "enum": [
                      "MANUAL",
                      "AUTOMATIC"
                    ],
                    "default": "MANUAL"
                  },
                  "max_active_cases": {
                    "type": "integer",
                    "nullable": true,
                    "minimum": 1,
                    "description": "Ambang batas mode otomatis: \"kurang dari N kasus cetak biru ini yang ditugaskan\"."
                  },
                  "escalation_enabled": {
                    "type": "boolean",
                    "default": false
                  },
                  "escalation_blueprint": {
                    "type": "string",
                    "format": "uuid",
                    "nullable": true,
                    "description": "UUID blueprint target. Tidak diberlakukan saat penyimpanan, tetapi tindakan eskalasi gagal dengan 400 sampai escalation_enabled dan escalation_blueprint keduanya diatur."
                  },
                  "transfer_enabled": {
                    "type": "boolean",
                    "default": false
                  },
                  "four_eyes_checker_blueprint": {
                    "type": "string",
                    "format": "uuid",
                    "nullable": true,
                    "description": "Mengatur ini akan mengaktifkan peninjauan 4-eyes: resolusi pada blueprint ini masuk ke antrean blueprint pemeriksa."
                  },
                  "require_resolution_note": {
                    "type": "boolean",
                    "default": false
                  },
                  "content_config": {
                    "$ref": "#/components/schemas/CaseContentConfig"
                  },
                  "is_active": {
                    "type": "boolean",
                    "default": true
                  },
                  "default_deadline_hours": {
                    "type": "integer",
                    "nullable": true,
                    "minimum": 1,
                    "maximum": 8760,
                    "description": "Batas waktu default untuk kasus yang baru dibuka. Batas waktu kasus yang sudah ada tidak berubah."
                  },
                  "publish": {
                    "type": "boolean",
                    "writeOnly": true,
                    "default": true,
                    "description": "Setel ke false untuk menyimpan draf yang belum pernah dipublikasikan. Rekaman tetap tidak aktif pada versi 0 hingga draf tersebut dipublikasikan secara eksplisit. Menghilangkan kolom ini mempertahankan pembuatan langsung untuk integrasi yang ada."
                  }
                }
              },
              "example": {
                "name": "AML investigation",
                "assignee_pool": [
                  "9a000000-0000-4000-8000-0000000000aa"
                ],
                "assignment_method": "AUTOMATIC",
                "max_active_cases": 15,
                "require_resolution_note": true,
                "content_config": {
                  "aml_control": {
                    "enabled": true,
                    "financial": true,
                    "identity": false
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/cases/blueprints/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"name\": \"AML investigation\", \"assignee_pool\": [\"9a000000-0000-4000-8000-0000000000aa\"], \"assignment_method\": \"AUTOMATIC\", \"max_active_cases\": 15, \"require_resolution_note\": true, \"content_config\": {\"aml_control\": {\"enabled\": true, \"financial\": true, \"identity\": false}}}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.blueprints.create(\n    name=\"AML investigation\",\n    assignee_pool=[\"9a000000-0000-4000-8000-0000000000aa\"],\n    assignment_method=\"AUTOMATIC\",\n    max_active_cases=15,\n    require_resolution_note=True,\n    content_config={\n        \"aml_control\": {\n            \"enabled\": True,\n            \"financial\": True,\n            \"identity\": False,\n        },\n    },\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.blueprints.create({\n  name: \"AML investigation\",\n  assignee_pool: [\"9a000000-0000-4000-8000-0000000000aa\"],\n  assignment_method: \"AUTOMATIC\",\n  max_active_cases: 15,\n  require_resolution_note: true,\n  content_config: {\n    aml_control: {\n      enabled: true,\n      financial: true,\n      identity: false,\n    },\n  },\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.Blueprints.Create(ctx, didit.CasesBlueprintsCreateParams{\n\tName:                  \"AML investigation\",\n\tAssigneePool:          []string{\"9a000000-0000-4000-8000-0000000000aa\"},\n\tAssignmentMethod:      didit.Some(didit.CasesBlueprintsCreateParamsAssignmentMethod(\"AUTOMATIC\")),\n\tMaxActiveCases:        didit.Int(15),\n\tRequireResolutionNote: didit.Bool(true),\n\tContentConfig: didit.Some(didit.CaseContentConfigParam{\n\t\tAMLControl: didit.Some(didit.CaseContentConfigParamAMLControl{\n\t\t\tEnabled:   didit.Bool(true),\n\t\t\tFinancial: didit.Bool(true),\n\t\t\tIdentity:  didit.Bool(false),\n\t\t}),\n\t}),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.List;\nimport me.didit.Didit;\nimport me.didit.types.CaseContentConfig;\nimport me.didit.types.CasesBlueprintsCreateParams;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().blueprints().create(CasesBlueprintsCreateParams.builder()\n        .name(\"AML investigation\")\n        .assigneePool(List.of(\"9a000000-0000-4000-8000-0000000000aa\"))\n        .assignmentMethod(CasesBlueprintsCreateParams.AssignmentMethod.of(\"AUTOMATIC\"))\n        .maxActiveCases(15L)\n        .requireResolutionNote(true)\n        .contentConfig(CaseContentConfig.builder()\n                .amlControl(CaseContentConfig.AmlControl.builder()\n                        .enabled(true)\n                        .financial(true)\n                        .identity(false)\n                        .build())\n                .build())\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->cases->blueprints->create([\n    'name' => 'AML investigation',\n    'assignee_pool' => ['9a000000-0000-4000-8000-0000000000aa'],\n    'assignment_method' => 'AUTOMATIC',\n    'max_active_cases' => 15,\n    'require_resolution_note' => true,\n    'content_config' => [\n        'aml_control' => [\n            'enabled' => true,\n            'financial' => true,\n            'identity' => false,\n        ],\n    ],\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.blueprints.create(\n  name: \"AML investigation\",\n  assignee_pool: [\"9a000000-0000-4000-8000-0000000000aa\"],\n  assignment_method: \"AUTOMATIC\",\n  max_active_cases: 15,\n  require_resolution_note: true,\n  content_config: {\n    aml_control: {\n      enabled: true,\n      financial: true,\n      identity: false,\n    },\n  }\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.Blueprints.CreateAsync(new CasesBlueprintsCreateParams\n{\n    Name = \"AML investigation\",\n    AssigneePool = new string[] { \"9a000000-0000-4000-8000-0000000000aa\" },\n    AssignmentMethod = new CasesBlueprintsCreateParamsAssignmentMethod(\"AUTOMATIC\"),\n    MaxActiveCases = 15,\n    RequireResolutionNote = true,\n    ContentConfig = new CaseContentConfig\n    {\n        AmlControl = new CaseContentConfigAmlControl\n        {\n            Enabled = true,\n            Financial = true,\n            Identity = false,\n        },\n    },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "201": {
            "description": "Blueprint dibuat.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CaseBlueprintDetail"
                }
              }
            }
          },
          "400": {
            "description": "Nama lebih dari 24 karakter, assignee_pool kosong, atau blueprint referensi silang (eskalasi/pemeriksa) tidak ditemukan.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/cases/blueprints/{blueprint_uuid}/": {
      "get": {
        "summary": "Dapatkan cetak biru",
        "description": "Ambil blueprint, termasuk sumber pembuatan yang terhubung (konfigurasi AML, aturan transaksi, node alur kerja) dan blueprint mana yang melakukan eskalasi ke blueprint ini.",
        "operationId": "get_case_blueprint",
        "x-didit-sdk": {
          "resource": "cases.blueprints",
          "method": "retrieve",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Case Blueprints"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID organisasi."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID aplikasi."
          },
          {
            "name": "blueprint_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "b1de0000-0000-4000-8000-000000000002"
            },
            "description": "UUID Blueprint."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/cases/blueprints/b1de0000-0000-4000-8000-000000000002/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.blueprints.retrieve(\n    \"b1de0000-0000-4000-8000-000000000002\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.blueprints.retrieve(\"b1de0000-0000-4000-8000-000000000002\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.Blueprints.Retrieve(ctx, \"b1de0000-0000-4000-8000-000000000002\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().blueprints().retrieve(\"b1de0000-0000-4000-8000-000000000002\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->cases->blueprints->retrieve('b1de0000-0000-4000-8000-000000000002');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.blueprints.retrieve(\"b1de0000-0000-4000-8000-000000000002\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.Blueprints.RetrieveAsync(\"b1de0000-0000-4000-8000-000000000002\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "Detail blueprint.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CaseBlueprintDetail"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      },
      "patch": {
        "summary": "Perbarui cetak biru",
        "description": "Perbarui sebagian pengaturan umum atau content_config blueprint.",
        "operationId": "update_case_blueprint",
        "x-didit-sdk": {
          "resource": "cases.blueprints",
          "method": "update",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Case Blueprints"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID organisasi."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID aplikasi."
          },
          {
            "name": "blueprint_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "b1de0000-0000-4000-8000-000000000002"
            },
            "description": "UUID Blueprint."
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "maxLength": 24,
                    "description": "Maksimal 24 karakter, misalnya \"investigasi AML\"."
                  },
                  "description": {
                    "type": "string",
                    "nullable": true
                  },
                  "assignee_pool": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "minItems": 1,
                    "description": "Daftar UUID Pengguna. Array kosong ditolak dengan \"Pilih setidaknya satu penerima tugas\"."
                  },
                  "assignment_method": {
                    "type": "string",
                    "enum": [
                      "MANUAL",
                      "AUTOMATIC"
                    ]
                  },
                  "max_active_cases": {
                    "type": "integer",
                    "nullable": true,
                    "minimum": 1,
                    "description": "Ambang batas mode otomatis: \"kurang dari N kasus cetak biru ini yang ditugaskan\"."
                  },
                  "escalation_enabled": {
                    "type": "boolean"
                  },
                  "escalation_blueprint": {
                    "type": "string",
                    "format": "uuid",
                    "nullable": true,
                    "description": "UUID blueprint target. Tidak diberlakukan saat penyimpanan, tetapi tindakan eskalasi gagal dengan 400 sampai escalation_enabled dan escalation_blueprint keduanya diatur."
                  },
                  "transfer_enabled": {
                    "type": "boolean"
                  },
                  "four_eyes_checker_blueprint": {
                    "type": "string",
                    "format": "uuid",
                    "nullable": true,
                    "description": "Mengatur ini akan mengaktifkan peninjauan 4-eyes: resolusi pada blueprint ini masuk ke antrean blueprint pemeriksa."
                  },
                  "require_resolution_note": {
                    "type": "boolean"
                  },
                  "content_config": {
                    "$ref": "#/components/schemas/CaseContentConfig"
                  },
                  "is_active": {
                    "type": "boolean"
                  },
                  "default_deadline_hours": {
                    "type": "integer",
                    "nullable": true,
                    "minimum": 1,
                    "maximum": 8760,
                    "description": "Batas waktu default untuk kasus yang baru dibuka. Batas waktu kasus yang sudah ada tidak berubah."
                  },
                  "expected_version": {
                    "type": "integer",
                    "minimum": 1,
                    "description": "Versi yang dibuka oleh editor. Versi usang mengembalikan 409 tanpa mengubah kebijakan peninjauan."
                  }
                }
              },
              "example": {
                "transfer_enabled": true
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X PATCH 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/cases/blueprints/b1de0000-0000-4000-8000-000000000002/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"transfer_enabled\": true}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.blueprints.update(\n    \"b1de0000-0000-4000-8000-000000000002\",\n    transfer_enabled=True,\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.blueprints.update(\"b1de0000-0000-4000-8000-000000000002\", {\n  transfer_enabled: true,\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.Blueprints.Update(ctx, \"b1de0000-0000-4000-8000-000000000002\", didit.CasesBlueprintsUpdateParams{\n\tTransferEnabled: didit.Bool(true),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.CasesBlueprintsUpdateParams;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().blueprints().update(\"b1de0000-0000-4000-8000-000000000002\", CasesBlueprintsUpdateParams.builder()\n        .transferEnabled(true)\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->cases->blueprints->update('b1de0000-0000-4000-8000-000000000002', [\n    'transfer_enabled' => true,\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.blueprints.update(\n  \"b1de0000-0000-4000-8000-000000000002\",\n  transfer_enabled: true\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.Blueprints.UpdateAsync(\"b1de0000-0000-4000-8000-000000000002\", new CasesBlueprintsUpdateParams\n{\n    TransferEnabled = true,\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "Cetak biru yang diperbarui.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CaseBlueprintDetail"
                }
              }
            }
          },
          "409": {
            "description": "Kebijakan peninjauan telah berubah sejak expected_version. Tinjau versi terbaru sebelum mencoba lagi."
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      },
      "delete": {
        "summary": "Hapus blueprint",
        "description": "Hapus blueprint. Penghapusan selalu berhasil dan tidak memengaruhi kasus blueprint tersebut: kasus yang ada tetap mempertahankan referensi blueprint miliknya dan pengaturannya tetap berlaku untuk kasus-kasus tersebut. Blueprint yang dihapus tidak lagi muncul dalam daftar blueprint dan tidak dapat lagi dipilih sebagai target transfer; jika maker blueprint dihapus saat resolusi sedang menunggu persetujuan 4-eyes, resolusi yang ditolak akan membiarkan kasus tetap berada pada checker blueprint.",
        "operationId": "delete_case_blueprint",
        "x-didit-sdk": {
          "resource": "cases.blueprints",
          "method": "delete",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Case Blueprints"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID organisasi."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID aplikasi."
          },
          {
            "name": "blueprint_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "b1de0000-0000-4000-8000-000000000002"
            },
            "description": "UUID Blueprint."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X DELETE 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/cases/blueprints/b1de0000-0000-4000-8000-000000000002/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nclient.cases.blueprints.delete(\n    \"b1de0000-0000-4000-8000-000000000002\",\n)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nawait didit.cases.blueprints.delete(\"b1de0000-0000-4000-8000-000000000002\");"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nif err := client.Cases.Blueprints.Delete(ctx, \"b1de0000-0000-4000-8000-000000000002\"); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nclient.cases().blueprints().delete(\"b1de0000-0000-4000-8000-000000000002\");"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$didit->cases->blueprints->delete('b1de0000-0000-4000-8000-000000000002');"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\ndidit.cases.blueprints.delete(\"b1de0000-0000-4000-8000-000000000002\")"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nawait client.Cases.Blueprints.DeleteAsync(\"b1de0000-0000-4000-8000-000000000002\");"
          }
        ],
        "responses": {
          "204": {
            "description": "Blueprint dihapus."
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/cases/blueprints/presets/": {
      "get": {
        "summary": "Daftar preset blueprint",
        "description": "Mencantumkan daftar empat preset bawaan (Screening hit, AML investigation, Suspicious activity, KYC review) beserta content_config-nya dan apakah masing-masing telah terpasang pada aplikasi ini.",
        "operationId": "list_case_blueprint_presets",
        "x-didit-sdk": {
          "resource": "cases.blueprints",
          "method": "list_presets",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Case Blueprints"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID organisasi."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID aplikasi."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/cases/blueprints/presets/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.blueprints.list_presets()\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.blueprints.listPresets();\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.Blueprints.ListPresets(ctx)\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().blueprints().listPresets();\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->cases->blueprints->listPresets();\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.blueprints.list_presets\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.Blueprints.ListPresetsAsync();\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "Katalog prasetel.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "results": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "preset_key": {
                            "type": "string",
                            "enum": [
                              "screening_hit",
                              "aml_investigation",
                              "suspicious_activity",
                              "kyc"
                            ]
                          },
                          "name": {
                            "type": "string"
                          },
                          "description": {
                            "type": "string"
                          },
                          "content_config": {
                            "$ref": "#/components/schemas/CaseContentConfig"
                          },
                          "installed": {
                            "type": "boolean"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/cases/blueprints/presets/install/": {
      "post": {
        "summary": "Instal preset blueprint",
        "description": "Salin satu atau beberapa preset ke dalam aplikasi sebagai cetak biru yang dapat diedit. Idempoten per preset_key; jangan sertakan preset_keys untuk menginstal setiap preset yang belum diinstal.",
        "operationId": "install_case_blueprint_presets",
        "x-didit-sdk": {
          "resource": "cases.blueprints",
          "method": "install_presets",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Case Blueprints"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID organisasi."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID aplikasi."
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "preset_keys": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "nullable": true,
                    "description": "Subset dari screening_hit, aml_investigation, suspicious_activity, kyc. Jangan sertakan untuk memasang semuanya."
                  }
                }
              },
              "example": {
                "preset_keys": [
                  "aml_investigation",
                  "kyc"
                ]
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/cases/blueprints/presets/install/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"preset_keys\": [\"aml_investigation\", \"kyc\"]}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.blueprints.install_presets(\n    preset_keys=[\"aml_investigation\", \"kyc\"],\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.blueprints.installPresets({\n  preset_keys: [\"aml_investigation\", \"kyc\"],\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.Blueprints.InstallPresets(ctx, didit.CasesBlueprintsInstallPresetsParams{\n\tPresetKeys: didit.Some([]string{\"aml_investigation\", \"kyc\"}),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.List;\nimport me.didit.Didit;\nimport me.didit.types.CasesBlueprintsInstallPresetsParams;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().blueprints().installPresets(CasesBlueprintsInstallPresetsParams.builder()\n        .presetKeys(List.of(\"aml_investigation\", \"kyc\"))\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->cases->blueprints->installPresets([\n    'preset_keys' => ['aml_investigation', 'kyc'],\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.blueprints.install_presets(preset_keys: [\"aml_investigation\", \"kyc\"])\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.Blueprints.InstallPresetsAsync(new CasesBlueprintsInstallPresetsParams\n{\n    PresetKeys = new string[] { \"aml_investigation\", \"kyc\" },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "201": {
            "description": "Satu atau lebih preset terpasang.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CaseBlueprintPresetInstallResult"
                }
              }
            }
          },
          "200": {
            "description": "Tidak ada preset baru untuk diinstal (semua preset yang diminta sudah ada).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CaseBlueprintPresetInstallResult"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/report-templates/": {
      "get": {
        "summary": "Mencantumkan templat laporan",
        "description": "Daftar templat laporan FIU untuk aplikasi.",
        "operationId": "list_report_templates",
        "x-didit-sdk": {
          "resource": "report_templates",
          "method": "list",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Report Templates"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID organisasi."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID aplikasi."
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 50,
              "minimum": 1
            },
            "description": "Ukuran halaman."
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 0,
              "minimum": 0
            },
            "description": "Offset berbasis nol."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/report-templates/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nfor item in client.report_templates.list():\n    print(item)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nfor await (const item of didit.reportTemplates.list()) {\n  console.log(item);\n}"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\niter := client.ReportTemplates.ListAutoPaging(ctx, didit.ReportTemplatesListParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nfor (var item : client.reportTemplates().list()) {\n    System.out.println(item);\n}"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\nforeach ($didit->reportTemplates->list() as $item) {\n    print_r($item->toArray());\n}"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\ndidit.report_templates.list.auto_paging_each do |item|\n  puts item.to_h\nend"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.ReportTemplates.ListAsync())\n{\n    Console.WriteLine(JsonSerializer.Serialize(item));\n}"
          }
        ],
        "responses": {
          "200": {
            "description": "Templat terpaginasi.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "count": {
                      "type": "integer",
                      "description": "Jumlah baris yang cocok, dibatasi pada 100 demi performa."
                    },
                    "next": {
                      "type": "string",
                      "nullable": true
                    },
                    "previous": {
                      "type": "string",
                      "nullable": true
                    },
                    "results": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/ReportTemplateDetail"
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      },
      "post": {
        "summary": "Buat templat laporan",
        "description": "Buat templat header goAML yang dapat digunakan kembali per yurisdiksi dan per jenis laporan. Ditolak dengan 400 jika salah satu kolom wajib tingkat templat (rentity_id, submission_code, currency_code_local) tidak ada di field_config; templat yang tidak valid tidak dapat disimpan atau digunakan untuk membuat laporan. Kolom header per pengajuan (action, submission_date, transactions) diberlakukan pada saat validasi/finalisasi laporan.",
        "operationId": "create_report_template",
        "x-didit-sdk": {
          "resource": "report_templates",
          "method": "create",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Report Templates"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID organisasi."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID aplikasi."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "name",
                  "jurisdiction",
                  "report_type"
                ],
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "jurisdiction": {
                    "type": "string",
                    "minLength": 2,
                    "maxLength": 2,
                    "description": "Kode negara ISO 3166-1 alpha-2, diubah menjadi huruf besar saat disimpan."
                  },
                  "report_type": {
                    "type": "string",
                    "enum": [
                      "SAR",
                      "STR",
                      "CTR",
                      "TTR",
                      "UTR",
                      "IFT",
                      "CBR",
                      "TFR"
                    ]
                  },
                  "field_config": {
                    "type": "object",
                    "description": "Nilai default header goAML yang dapat digunakan kembali. Kolom wajib tingkat templat: rentity_id, submission_code, dan currency_code_local (3 huruf). Opsional: enabled_fields (blok laporan opsional mana yang disertakan) ditambah nilai default reporting_person, location, reason, dan action. Kolom header per pengajuan (action, submission_date, transactions, jurisdiction) diberlakukan saat laporan divalidasi atau difinalisasi, bukan pada templat."
                  }
                }
              },
              "example": {
                "name": "US SAR default",
                "jurisdiction": "US",
                "report_type": "SAR",
                "field_config": {
                  "rentity_id": "FIU-US-00123",
                  "submission_code": "E",
                  "currency_code_local": "USD"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/report-templates/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"name\": \"US SAR default\", \"jurisdiction\": \"US\", \"report_type\": \"SAR\", \"field_config\": {\"rentity_id\": \"FIU-US-00123\", \"submission_code\": \"E\", \"currency_code_local\": \"USD\"}}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.report_templates.create(\n    name=\"US SAR default\",\n    jurisdiction=\"US\",\n    report_type=\"SAR\",\n    field_config={\"rentity_id\": \"FIU-US-00123\", \"submission_code\": \"E\", \"currency_code_local\": \"USD\"},\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.reportTemplates.create({\n  name: \"US SAR default\",\n  jurisdiction: \"US\",\n  report_type: \"SAR\",\n  field_config: { rentity_id: \"FIU-US-00123\", submission_code: \"E\", currency_code_local: \"USD\" },\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.ReportTemplates.Create(ctx, didit.ReportTemplatesCreateParams{\n\tName:         \"US SAR default\",\n\tJurisdiction: \"US\",\n\tReportType:   \"SAR\",\n\tFieldConfig:  didit.Some(map[string]any{\"rentity_id\": \"FIU-US-00123\", \"submission_code\": \"E\", \"currency_code_local\": \"USD\"}),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.ReportTemplatesCreateParams;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.reportTemplates().create(ReportTemplatesCreateParams.builder()\n        .name(\"US SAR default\")\n        .jurisdiction(\"US\")\n        .reportType(ReportTemplatesCreateParams.ReportType.of(\"SAR\"))\n        .fieldConfig(Map.of(\"rentity_id\", \"FIU-US-00123\", \"submission_code\", \"E\", \"currency_code_local\", \"USD\"))\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->reportTemplates->create([\n    'name' => 'US SAR default',\n    'jurisdiction' => 'US',\n    'report_type' => 'SAR',\n    'field_config' => ['rentity_id' => 'FIU-US-00123', 'submission_code' => 'E', 'currency_code_local' => 'USD'],\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.report_templates.create(\n  name: \"US SAR default\",\n  jurisdiction: \"US\",\n  report_type: \"SAR\",\n  field_config: { rentity_id: \"FIU-US-00123\", submission_code: \"E\", currency_code_local: \"USD\" }\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.ReportTemplates.CreateAsync(new ReportTemplatesCreateParams\n{\n    Name = \"US SAR default\",\n    Jurisdiction = \"US\",\n    ReportType = \"SAR\",\n    FieldConfig = new Dictionary<string, object> { [\"rentity_id\"] = \"FIU-US-00123\", [\"submission_code\"] = \"E\", [\"currency_code_local\"] = \"USD\" },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "201": {
            "description": "Templat dibuat.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReportTemplateDetail"
                }
              }
            }
          },
          "400": {
            "description": "Yurisdiksi tidak dikenal, atau field_config gagal dalam validasi kolom wajib.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/report-templates/{template_uuid}/": {
      "get": {
        "summary": "Dapatkan templat laporan",
        "description": "Ambil templat laporan.",
        "operationId": "get_report_template",
        "x-didit-sdk": {
          "resource": "report_templates",
          "method": "retrieve",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Report Templates"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID organisasi."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID aplikasi."
          },
          {
            "name": "template_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "7ec00000-0000-4000-8000-000000000006"
            },
            "description": "UUID templat laporan."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/report-templates/7ec00000-0000-4000-8000-000000000006/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.report_templates.retrieve(\n    \"7ec00000-0000-4000-8000-000000000006\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.reportTemplates.retrieve(\"7ec00000-0000-4000-8000-000000000006\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.ReportTemplates.Retrieve(ctx, \"7ec00000-0000-4000-8000-000000000006\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.reportTemplates().retrieve(\"7ec00000-0000-4000-8000-000000000006\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->reportTemplates->retrieve('7ec00000-0000-4000-8000-000000000006');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.report_templates.retrieve(\"7ec00000-0000-4000-8000-000000000006\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.ReportTemplates.RetrieveAsync(\"7ec00000-0000-4000-8000-000000000006\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "Detail templat.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReportTemplateDetail"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      },
      "patch": {
        "summary": "Perbarui templat laporan",
        "description": "Perbarui sebagian templat laporan. Memvalidasi ulang kolom wajib goAML saat disimpan.",
        "operationId": "update_report_template",
        "x-didit-sdk": {
          "resource": "report_templates",
          "method": "update",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Report Templates"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID organisasi."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID aplikasi."
          },
          {
            "name": "template_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "7ec00000-0000-4000-8000-000000000006"
            },
            "description": "UUID templat laporan."
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "jurisdiction": {
                    "type": "string",
                    "minLength": 2,
                    "maxLength": 2,
                    "description": "Kode negara ISO 3166-1 alpha-2, diubah menjadi huruf besar saat disimpan."
                  },
                  "report_type": {
                    "type": "string",
                    "enum": [
                      "SAR",
                      "STR",
                      "CTR",
                      "TTR",
                      "UTR",
                      "IFT",
                      "CBR",
                      "TFR"
                    ]
                  },
                  "field_config": {
                    "type": "object",
                    "description": "Nilai default header goAML yang dapat digunakan kembali. Kolom wajib tingkat templat: rentity_id, submission_code, dan currency_code_local (3 huruf). Opsional: enabled_fields (blok laporan opsional mana yang disertakan) ditambah nilai default reporting_person, location, reason, dan action. Kolom header per pengajuan (action, submission_date, transactions, jurisdiction) diberlakukan saat laporan divalidasi atau difinalisasi, bukan pada templat."
                  }
                }
              },
              "example": {
                "field_config": {
                  "rentity_id": "FIU-US-00124"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X PATCH 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/report-templates/7ec00000-0000-4000-8000-000000000006/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"field_config\": {\"rentity_id\": \"FIU-US-00124\"}}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.report_templates.update(\n    \"7ec00000-0000-4000-8000-000000000006\",\n    field_config={\"rentity_id\": \"FIU-US-00124\"},\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.reportTemplates.update(\"7ec00000-0000-4000-8000-000000000006\", {\n  field_config: { rentity_id: \"FIU-US-00124\" },\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.ReportTemplates.Update(ctx, \"7ec00000-0000-4000-8000-000000000006\", didit.ReportTemplatesUpdateParams{\n\tFieldConfig: didit.Some(map[string]any{\"rentity_id\": \"FIU-US-00124\"}),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.ReportTemplatesUpdateParams;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.reportTemplates().update(\"7ec00000-0000-4000-8000-000000000006\", ReportTemplatesUpdateParams.builder()\n        .fieldConfig(Map.of(\"rentity_id\", \"FIU-US-00124\"))\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->reportTemplates->update('7ec00000-0000-4000-8000-000000000006', [\n    'field_config' => ['rentity_id' => 'FIU-US-00124'],\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.report_templates.update(\n  \"7ec00000-0000-4000-8000-000000000006\",\n  field_config: { rentity_id: \"FIU-US-00124\" }\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.ReportTemplates.UpdateAsync(\"7ec00000-0000-4000-8000-000000000006\", new ReportTemplatesUpdateParams\n{\n    FieldConfig = new Dictionary<string, object> { [\"rentity_id\"] = \"FIU-US-00124\" },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "Templat yang diperbarui.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReportTemplateDetail"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      },
      "delete": {
        "summary": "Hapus templat laporan",
        "description": "Hapus templat laporan. Laporan yang sudah dibuat dari templat tersebut tidak akan terpengaruh.",
        "operationId": "delete_report_template",
        "x-didit-sdk": {
          "resource": "report_templates",
          "method": "delete",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Report Templates"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID organisasi."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID aplikasi."
          },
          {
            "name": "template_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "7ec00000-0000-4000-8000-000000000006"
            },
            "description": "UUID templat laporan."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X DELETE 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/report-templates/7ec00000-0000-4000-8000-000000000006/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nclient.report_templates.delete(\n    \"7ec00000-0000-4000-8000-000000000006\",\n)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nawait didit.reportTemplates.delete(\"7ec00000-0000-4000-8000-000000000006\");"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nif err := client.ReportTemplates.Delete(ctx, \"7ec00000-0000-4000-8000-000000000006\"); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nclient.reportTemplates().delete(\"7ec00000-0000-4000-8000-000000000006\");"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$didit->reportTemplates->delete('7ec00000-0000-4000-8000-000000000006');"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\ndidit.report_templates.delete(\"7ec00000-0000-4000-8000-000000000006\")"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nawait client.ReportTemplates.DeleteAsync(\"7ec00000-0000-4000-8000-000000000006\");"
          }
        ],
        "responses": {
          "204": {
            "description": "Templat dihapus."
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/cases/{case_uuid}/regulatory-reports/": {
      "get": {
        "summary": "Mencantumkan laporan untuk kasus",
        "description": "Daftar laporan FIU yang dibuat untuk kasus ini.",
        "operationId": "list_case_regulatory_reports",
        "x-didit-sdk": {
          "resource": "cases.regulatory_reports",
          "method": "list",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Regulatory Reports"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID organisasi."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID aplikasi."
          },
          {
            "name": "case_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "c1a5e000-0000-4000-8000-000000000001"
            },
            "description": "UUID kasus."
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 50,
              "minimum": 1
            },
            "description": "Ukuran halaman."
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 0,
              "minimum": 0
            },
            "description": "Offset berbasis nol."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/cases/c1a5e000-0000-4000-8000-000000000001/regulatory-reports/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nfor item in client.cases.regulatory_reports.list(\n    \"c1a5e000-0000-4000-8000-000000000001\",\n):\n    print(item)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nfor await (const item of didit.cases.regulatoryReports.list(\"c1a5e000-0000-4000-8000-000000000001\")) {\n  console.log(item);\n}"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\niter := client.Cases.RegulatoryReports.ListAutoPaging(ctx, \"c1a5e000-0000-4000-8000-000000000001\", didit.CasesRegulatoryReportsListParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nfor (var item : client.cases().regulatoryReports().list(\"c1a5e000-0000-4000-8000-000000000001\")) {\n    System.out.println(item);\n}"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\nforeach ($didit->cases->regulatoryReports->list('c1a5e000-0000-4000-8000-000000000001') as $item) {\n    print_r($item->toArray());\n}"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\ndidit.cases.regulatory_reports.list(\"c1a5e000-0000-4000-8000-000000000001\").auto_paging_each do |item|\n  puts item.to_h\nend"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.Cases.RegulatoryReports.ListAsync(\"c1a5e000-0000-4000-8000-000000000001\"))\n{\n    Console.WriteLine(JsonSerializer.Serialize(item));\n}"
          }
        ],
        "responses": {
          "200": {
            "description": "Laporan terpaginasi untuk kasus ini.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RegulatoryReportList"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      },
      "post": {
        "summary": "Buat laporan dari kasus",
        "description": "Buat draf laporan FIU untuk kasus: status DRAFT, diisi otomatis dari templat opsional ditambah subjek kasus, transaksi tertaut, dan narasi. Validasi lalu finalisasi untuk menghasilkan XML dan PDF goAML.",
        "operationId": "create_case_regulatory_report",
        "x-didit-sdk": {
          "resource": "cases.regulatory_reports",
          "method": "create",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Regulatory Reports"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID organisasi."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID aplikasi."
          },
          {
            "name": "case_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "c1a5e000-0000-4000-8000-000000000001"
            },
            "description": "UUID kasus."
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "report_type": {
                    "type": "string",
                    "enum": [
                      "SAR",
                      "STR",
                      "CTR",
                      "TTR",
                      "UTR",
                      "IFT",
                      "CBR",
                      "TFR"
                    ],
                    "description": "Wajib kecuali jika templat diberikan; report_type templat akan digunakan jika tidak."
                  },
                  "jurisdiction": {
                    "type": "string",
                    "minLength": 2,
                    "maxLength": 2,
                    "description": "Wajib kecuali jika templat diberikan."
                  },
                  "template": {
                    "type": "string",
                    "format": "uuid",
                    "nullable": true,
                    "description": "UUID templat laporan; field_config miliknya mengisi draf sebelum data turunan kasus digabungkan."
                  },
                  "transactions": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "nullable": true,
                    "description": "Transaksi yang akan dilampirkan; defaultnya adalah transaksi yang ditautkan ke kasus."
                  },
                  "rentity_id": {
                    "type": "string",
                    "nullable": true
                  },
                  "rentity_branch": {
                    "type": "string",
                    "nullable": true
                  },
                  "submission_code": {
                    "type": "string",
                    "enum": [
                      "E",
                      "M"
                    ],
                    "default": "E"
                  },
                  "entity_reference": {
                    "type": "string",
                    "nullable": true
                  },
                  "fiu_ref_number": {
                    "type": "string",
                    "nullable": true
                  },
                  "currency_code_local": {
                    "type": "string",
                    "minLength": 3,
                    "maxLength": 3,
                    "nullable": true
                  },
                  "submission_date": {
                    "type": "string",
                    "format": "date-time",
                    "nullable": true
                  },
                  "reporting_person": {
                    "type": "object"
                  },
                  "location": {
                    "type": "object"
                  },
                  "reason": {
                    "type": "string",
                    "nullable": true
                  },
                  "action": {
                    "type": "string",
                    "nullable": true
                  },
                  "activity": {
                    "type": "string",
                    "nullable": true
                  },
                  "narrative": {
                    "type": "object",
                    "properties": {
                      "who": {
                        "type": "string"
                      },
                      "what": {
                        "type": "string"
                      },
                      "when": {
                        "type": "string"
                      },
                      "where": {
                        "type": "string"
                      },
                      "why": {
                        "type": "string"
                      },
                      "how": {
                        "type": "string"
                      }
                    }
                  },
                  "report_indicators": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  },
                  "included_fields": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  }
                }
              },
              "example": {
                "template": "7ec00000-0000-4000-8000-000000000006"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/cases/c1a5e000-0000-4000-8000-000000000001/regulatory-reports/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"template\": \"7ec00000-0000-4000-8000-000000000006\"}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.regulatory_reports.create(\n    \"c1a5e000-0000-4000-8000-000000000001\",\n    template=\"7ec00000-0000-4000-8000-000000000006\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.regulatoryReports.create(\"c1a5e000-0000-4000-8000-000000000001\", {\n  template: \"7ec00000-0000-4000-8000-000000000006\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.RegulatoryReports.Create(ctx, \"c1a5e000-0000-4000-8000-000000000001\", didit.CasesRegulatoryReportsCreateParams{\n\tTemplate: didit.String(\"7ec00000-0000-4000-8000-000000000006\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.CasesRegulatoryReportsCreateParams;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().regulatoryReports().create(\"c1a5e000-0000-4000-8000-000000000001\", CasesRegulatoryReportsCreateParams.builder()\n        .template(\"7ec00000-0000-4000-8000-000000000006\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->cases->regulatoryReports->create('c1a5e000-0000-4000-8000-000000000001', [\n    'template' => '7ec00000-0000-4000-8000-000000000006',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.regulatory_reports.create(\n  \"c1a5e000-0000-4000-8000-000000000001\",\n  template: \"7ec00000-0000-4000-8000-000000000006\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.RegulatoryReports.CreateAsync(\"c1a5e000-0000-4000-8000-000000000001\", new CasesRegulatoryReportsCreateParams\n{\n    Template = \"7ec00000-0000-4000-8000-000000000006\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "201": {
            "description": "Laporan draf berhasil dibuat.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RegulatoryReportDetail"
                }
              }
            }
          },
          "400": {
            "description": "Templat yang direferensikan tidak ditemukan.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/regulatory-reports/": {
      "get": {
        "summary": "Mencantumkan laporan",
        "description": "Daftar laporan FIU di seluruh aplikasi, secara opsional difilter berdasarkan status, report_type, atau kasus.",
        "operationId": "list_regulatory_reports",
        "x-didit-sdk": {
          "resource": "regulatory_reports",
          "method": "list",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Regulatory Reports"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID organisasi."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID aplikasi."
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 50,
              "minimum": 1
            },
            "description": "Ukuran halaman."
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 0,
              "minimum": 0
            },
            "description": "Offset berbasis nol."
          },
          {
            "name": "status",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "DRAFT",
                "VALIDATED",
                "FINALIZED"
              ]
            },
            "description": "Filter berdasarkan status."
          },
          {
            "name": "report_type",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "SAR",
                "STR",
                "CTR",
                "TTR",
                "UTR",
                "IFT",
                "CBR",
                "TFR"
              ]
            },
            "description": "Filter berdasarkan jenis laporan."
          },
          {
            "name": "case",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Filter laporan pada kasus ini."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/regulatory-reports/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nfor item in client.regulatory_reports.list():\n    print(item)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nfor await (const item of didit.regulatoryReports.list()) {\n  console.log(item);\n}"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\niter := client.RegulatoryReports.ListAutoPaging(ctx, didit.RegulatoryReportsListParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nfor (var item : client.regulatoryReports().list()) {\n    System.out.println(item);\n}"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\nforeach ($didit->regulatoryReports->list() as $item) {\n    print_r($item->toArray());\n}"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\ndidit.regulatory_reports.list.auto_paging_each do |item|\n  puts item.to_h\nend"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.RegulatoryReports.ListAsync())\n{\n    Console.WriteLine(JsonSerializer.Serialize(item));\n}"
          }
        ],
        "responses": {
          "200": {
            "description": "Laporan berpaginasi di seluruh aplikasi.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RegulatoryReportList"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      },
      "post": {
        "summary": "Buat laporan mandiri",
        "description": "Buat draf laporan FIU dari halaman Reports mandiri: kasus dan templat keduanya wajib diisi (berbeda dengan pembuatan dalam konteks kasus, yang dapat meniadakan templat).",
        "operationId": "create_standalone_regulatory_report",
        "x-didit-sdk": {
          "resource": "regulatory_reports",
          "method": "create",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Regulatory Reports"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID organisasi."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID aplikasi."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "case",
                  "template"
                ],
                "properties": {
                  "case": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "template": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "report_type": {
                    "type": "string",
                    "enum": [
                      "SAR",
                      "STR",
                      "CTR",
                      "TTR",
                      "UTR",
                      "IFT",
                      "CBR",
                      "TFR"
                    ],
                    "description": "Wajib kecuali jika templat diberikan; report_type templat akan digunakan jika tidak."
                  },
                  "jurisdiction": {
                    "type": "string",
                    "minLength": 2,
                    "maxLength": 2,
                    "description": "Wajib kecuali jika templat diberikan."
                  },
                  "transactions": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "nullable": true,
                    "description": "Transaksi yang akan dilampirkan; defaultnya adalah transaksi yang ditautkan ke kasus."
                  },
                  "rentity_id": {
                    "type": "string",
                    "nullable": true
                  },
                  "rentity_branch": {
                    "type": "string",
                    "nullable": true
                  },
                  "submission_code": {
                    "type": "string",
                    "enum": [
                      "E",
                      "M"
                    ],
                    "default": "E"
                  },
                  "entity_reference": {
                    "type": "string",
                    "nullable": true
                  },
                  "fiu_ref_number": {
                    "type": "string",
                    "nullable": true
                  },
                  "currency_code_local": {
                    "type": "string",
                    "minLength": 3,
                    "maxLength": 3,
                    "nullable": true
                  },
                  "submission_date": {
                    "type": "string",
                    "format": "date-time",
                    "nullable": true
                  },
                  "reporting_person": {
                    "type": "object"
                  },
                  "location": {
                    "type": "object"
                  },
                  "reason": {
                    "type": "string",
                    "nullable": true
                  },
                  "action": {
                    "type": "string",
                    "nullable": true
                  },
                  "activity": {
                    "type": "string",
                    "nullable": true
                  },
                  "narrative": {
                    "type": "object",
                    "properties": {
                      "who": {
                        "type": "string"
                      },
                      "what": {
                        "type": "string"
                      },
                      "when": {
                        "type": "string"
                      },
                      "where": {
                        "type": "string"
                      },
                      "why": {
                        "type": "string"
                      },
                      "how": {
                        "type": "string"
                      }
                    }
                  },
                  "report_indicators": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  },
                  "included_fields": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  }
                }
              },
              "example": {
                "case": "c1a5e000-0000-4000-8000-000000000001",
                "template": "7ec00000-0000-4000-8000-000000000006"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/regulatory-reports/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"case\": \"c1a5e000-0000-4000-8000-000000000001\", \"template\": \"7ec00000-0000-4000-8000-000000000006\"}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.regulatory_reports.create(\n    case=\"c1a5e000-0000-4000-8000-000000000001\",\n    template=\"7ec00000-0000-4000-8000-000000000006\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.regulatoryReports.create({\n  case: \"c1a5e000-0000-4000-8000-000000000001\",\n  template: \"7ec00000-0000-4000-8000-000000000006\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.RegulatoryReports.Create(ctx, didit.RegulatoryReportsCreateParams{\n\tCase:     \"c1a5e000-0000-4000-8000-000000000001\",\n\tTemplate: \"7ec00000-0000-4000-8000-000000000006\",\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.RegulatoryReportsCreateParams;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.regulatoryReports().create(RegulatoryReportsCreateParams.builder()\n        .case_(\"c1a5e000-0000-4000-8000-000000000001\")\n        .template(\"7ec00000-0000-4000-8000-000000000006\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->regulatoryReports->create([\n    'case' => 'c1a5e000-0000-4000-8000-000000000001',\n    'template' => '7ec00000-0000-4000-8000-000000000006',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.regulatory_reports.create(\n  case: \"c1a5e000-0000-4000-8000-000000000001\",\n  template: \"7ec00000-0000-4000-8000-000000000006\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.RegulatoryReports.CreateAsync(new RegulatoryReportsCreateParams\n{\n    Case = \"c1a5e000-0000-4000-8000-000000000001\",\n    Template = \"7ec00000-0000-4000-8000-000000000006\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "201": {
            "description": "Laporan draf berhasil dibuat.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RegulatoryReportDetail"
                }
              }
            }
          },
          "400": {
            "description": "Templat yang direferensikan tidak ditemukan.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/regulatory-reports/{report_uuid}/": {
      "get": {
        "summary": "Dapatkan laporan",
        "description": "Ambil laporan regulasi.",
        "operationId": "get_regulatory_report",
        "x-didit-sdk": {
          "resource": "regulatory_reports",
          "method": "retrieve",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Regulatory Reports"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID organisasi."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID aplikasi."
          },
          {
            "name": "report_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "5ec00000-0000-4000-8000-000000000007"
            },
            "description": "UUID laporan."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/regulatory-reports/5ec00000-0000-4000-8000-000000000007/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.regulatory_reports.retrieve(\n    \"5ec00000-0000-4000-8000-000000000007\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.regulatoryReports.retrieve(\"5ec00000-0000-4000-8000-000000000007\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.RegulatoryReports.Retrieve(ctx, \"5ec00000-0000-4000-8000-000000000007\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.regulatoryReports().retrieve(\"5ec00000-0000-4000-8000-000000000007\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->regulatoryReports->retrieve('5ec00000-0000-4000-8000-000000000007');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.regulatory_reports.retrieve(\"5ec00000-0000-4000-8000-000000000007\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.RegulatoryReports.RetrieveAsync(\"5ec00000-0000-4000-8000-000000000007\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "Detail laporan.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RegulatoryReportDetail"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      },
      "patch": {
        "summary": "Perbarui laporan",
        "description": "Edit kolom laporan draf atau yang divalidasi. Laporan yang sudah difinalisasi tidak dapat diedit (409).",
        "operationId": "update_regulatory_report",
        "x-didit-sdk": {
          "resource": "regulatory_reports",
          "method": "update",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Regulatory Reports"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID organisasi."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID aplikasi."
          },
          {
            "name": "report_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "5ec00000-0000-4000-8000-000000000007"
            },
            "description": "UUID laporan."
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "jurisdiction": {
                    "type": "string",
                    "minLength": 2,
                    "maxLength": 2
                  },
                  "rentity_id": {
                    "type": "string",
                    "nullable": true
                  },
                  "rentity_branch": {
                    "type": "string",
                    "nullable": true
                  },
                  "submission_code": {
                    "type": "string",
                    "enum": [
                      "E",
                      "M"
                    ],
                    "default": "E"
                  },
                  "entity_reference": {
                    "type": "string",
                    "nullable": true
                  },
                  "fiu_ref_number": {
                    "type": "string",
                    "nullable": true
                  },
                  "currency_code_local": {
                    "type": "string",
                    "minLength": 3,
                    "maxLength": 3,
                    "nullable": true
                  },
                  "submission_date": {
                    "type": "string",
                    "format": "date-time",
                    "nullable": true
                  },
                  "reporting_person": {
                    "type": "object"
                  },
                  "location": {
                    "type": "object"
                  },
                  "reason": {
                    "type": "string",
                    "nullable": true
                  },
                  "action": {
                    "type": "string",
                    "nullable": true
                  },
                  "activity": {
                    "type": "string",
                    "nullable": true
                  },
                  "narrative": {
                    "type": "object",
                    "properties": {
                      "who": {
                        "type": "string"
                      },
                      "what": {
                        "type": "string"
                      },
                      "when": {
                        "type": "string"
                      },
                      "where": {
                        "type": "string"
                      },
                      "why": {
                        "type": "string"
                      },
                      "how": {
                        "type": "string"
                      }
                    }
                  },
                  "report_indicators": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  },
                  "included_fields": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  }
                }
              },
              "example": {
                "rentity_id": "FIU-US-00123",
                "currency_code_local": "USD"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X PATCH 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/regulatory-reports/5ec00000-0000-4000-8000-000000000007/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"rentity_id\": \"FIU-US-00123\", \"currency_code_local\": \"USD\"}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.regulatory_reports.update(\n    \"5ec00000-0000-4000-8000-000000000007\",\n    rentity_id=\"FIU-US-00123\",\n    currency_code_local=\"USD\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.regulatoryReports.update(\"5ec00000-0000-4000-8000-000000000007\", {\n  rentity_id: \"FIU-US-00123\",\n  currency_code_local: \"USD\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.RegulatoryReports.Update(ctx, \"5ec00000-0000-4000-8000-000000000007\", didit.RegulatoryReportsUpdateParams{\n\tRentityID:         didit.String(\"FIU-US-00123\"),\n\tCurrencyCodeLocal: didit.String(\"USD\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.RegulatoryReportsUpdateParams;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.regulatoryReports().update(\"5ec00000-0000-4000-8000-000000000007\", RegulatoryReportsUpdateParams.builder()\n        .rentityId(\"FIU-US-00123\")\n        .currencyCodeLocal(\"USD\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->regulatoryReports->update('5ec00000-0000-4000-8000-000000000007', [\n    'rentity_id' => 'FIU-US-00123',\n    'currency_code_local' => 'USD',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.regulatory_reports.update(\n  \"5ec00000-0000-4000-8000-000000000007\",\n  rentity_id: \"FIU-US-00123\",\n  currency_code_local: \"USD\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.RegulatoryReports.UpdateAsync(\"5ec00000-0000-4000-8000-000000000007\", new RegulatoryReportsUpdateParams\n{\n    RentityId = \"FIU-US-00123\",\n    CurrencyCodeLocal = \"USD\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "Laporan yang diperbarui.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RegulatoryReportDetail"
                }
              }
            }
          },
          "409": {
            "description": "Laporan sudah selesai.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      },
      "delete": {
        "summary": "Hapus laporan",
        "description": "Hapus laporan regulasi secara permanen. Laporan, narasi dan alasan yang disalin, tautan transaksi, serta XML dan PDF goAML yang dihasilkan akan dihapus, termasuk setiap versi berkas yang tersimpan. Laporan menghilang dari daftar dan URL unduhan berhenti berfungsi. Catatan lain, termasuk kasus, transaksi, individu, dan perusahaan, tidak dihapus. Tindakan ini tidak dapat dibatalkan.\n\nLaporan berupa draf atau yang telah divalidasi dapat dihapus tanpa isi permintaan. Menghapus laporan yang telah difinalisasi memerlukan `confirm_delete: true` dalam isi permintaan. Jika laporan tidak ditemukan, permintaan mengembalikan `404`; jika laporan yang telah difinalisasi dikirim tanpa konfirmasi, permintaan mengembalikan `400` dan tidak ada yang dihapus.",
        "operationId": "delete_regulatory_report",
        "x-didit-sdk": {
          "resource": "regulatory_reports",
          "method": "delete",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Regulatory Reports"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID organisasi."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID aplikasi."
          },
          {
            "name": "report_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "5ec00000-0000-4000-8000-000000000007"
            },
            "description": "UUID laporan."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl (draft report)",
            "source": "curl -X DELETE 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/regulatory-reports/5ec00000-0000-4000-8000-000000000007/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "curl",
            "label": "curl (finalized report)",
            "source": "curl -X DELETE 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/regulatory-reports/5ec00000-0000-4000-8000-000000000007/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"confirm_delete\": true}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nclient.regulatory_reports.delete(\n    \"5ec00000-0000-4000-8000-000000000007\",\n    confirm_delete=True,\n)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nawait didit.regulatoryReports.delete(\"5ec00000-0000-4000-8000-000000000007\", {\n  confirm_delete: true,\n});"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.RegulatoryReportsDeleteParams;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nclient.regulatoryReports().delete(\"5ec00000-0000-4000-8000-000000000007\", RegulatoryReportsDeleteParams.builder()\n        .confirmDelete(true)\n        .build());"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$didit->regulatoryReports->delete('5ec00000-0000-4000-8000-000000000007', [\n    'confirm_delete' => true,\n]);"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\ndidit.regulatory_reports.delete(\n  \"5ec00000-0000-4000-8000-000000000007\",\n  confirm_delete: true\n)"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nawait client.RegulatoryReports.DeleteAsync(\"5ec00000-0000-4000-8000-000000000007\", new RegulatoryReportsDeleteParams\n{\n    ConfirmDelete = true,\n});"
          }
        ],
        "responses": {
          "204": {
            "description": "Laporan dihapus, termasuk file yang dihasilkannya."
          },
          "400": {
            "description": "Laporan yang sudah final dikirim tanpa `confirm_delete: true`. Tidak ada yang dihapus.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "confirm_delete": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                },
                "example": {
                  "confirm_delete": [
                    "This field is required to delete a finalized report."
                  ]
                }
              }
            }
          },
          "403": {
            "description": "Kunci API tidak dapat menghapus laporan. Endpoint memerlukan `write:cases`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Laporan tidak ditemukan di aplikasi ini.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "Laporan sudah dalam proses penghapusan. Ulangi permintaan untuk menyelesaikan penghapusan file-filenya.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "detail": "This report is being deleted. Retry deleting it to finish erasing its files.",
                  "code": "report_deletion_pending"
                }
              }
            }
          },
          "503": {
            "description": "File laporan tidak dapat dihapus saat ini. Laporan masih tetap ada. Ulangi permintaan.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "detail": "The report files could not be erased. Please retry deleting the report.",
                  "code": "report_storage_unavailable"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": false,
          "description": "Hanya wajib untuk laporan yang telah difinalisasi.",
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "confirm_delete": {
                    "type": "boolean",
                    "description": "Atur ke true untuk mengonfirmasi bahwa laporan yang telah difinalisasi beserta file yang dihasilkannya dihapus secara permanen."
                  }
                },
                "example": {
                  "confirm_delete": true
                }
              },
              "example": {
                "confirm_delete": true
              }
            }
          }
        }
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/regulatory-reports/{report_uuid}/validate/": {
      "post": {
        "summary": "Validasi laporan",
        "description": "Periksa laporan terhadap kolom header goAML wajib (ID entitas pelapor, kode pengiriman, mata uang lokal, tindakan yang diambil, tanggal pengiriman), ditambah setidaknya satu transaksi terlampir dan yurisdiksi 2 huruf, tanpa menghasilkan file apa pun. Juga menyimpan hasilnya pada laporan: validation_errors dan validated_at diperbarui, dan status laporan yang belum difinalisasi berubah menjadi VALIDATED (tidak ada kesalahan) atau kembali ke DRAFT (ada kesalahan).",
        "operationId": "validate_regulatory_report",
        "x-didit-sdk": {
          "resource": "regulatory_reports",
          "method": "validate",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Regulatory Reports"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID organisasi."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID aplikasi."
          },
          {
            "name": "report_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "5ec00000-0000-4000-8000-000000000007"
            },
            "description": "UUID laporan."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/regulatory-reports/5ec00000-0000-4000-8000-000000000007/validate/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.regulatory_reports.validate(\n    \"5ec00000-0000-4000-8000-000000000007\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.regulatoryReports.validate(\"5ec00000-0000-4000-8000-000000000007\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.RegulatoryReports.Validate(ctx, \"5ec00000-0000-4000-8000-000000000007\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.regulatoryReports().validate(\"5ec00000-0000-4000-8000-000000000007\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->regulatoryReports->validate('5ec00000-0000-4000-8000-000000000007');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.regulatory_reports.validate(\"5ec00000-0000-4000-8000-000000000007\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.RegulatoryReports.ValidateAsync(\"5ec00000-0000-4000-8000-000000000007\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "Hasil validasi.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "DRAFT",
                        "VALIDATED",
                        "FINALIZED"
                      ]
                    },
                    "is_valid": {
                      "type": "boolean"
                    },
                    "errors": {
                      "type": "array",
                      "description": "Kosong jika valid.",
                      "items": {
                        "type": "object",
                        "properties": {
                          "field": {
                            "type": "string"
                          },
                          "message": {
                            "type": "string"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/regulatory-reports/{report_uuid}/finalize/": {
      "post": {
        "summary": "Finalisasi laporan",
        "description": "Validasi ulang, lalu render XML dan PDF goAML serta unggah keduanya ke S3. Pada laporan SAR/STR/TFR, tindakan ini juga memindahkan alert transaksi kasus dari SAR Tertunda ke SAR diajukan.",
        "operationId": "finalize_regulatory_report",
        "x-didit-sdk": {
          "resource": "regulatory_reports",
          "method": "finalize",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Regulatory Reports"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID organisasi."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID aplikasi."
          },
          {
            "name": "report_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "5ec00000-0000-4000-8000-000000000007"
            },
            "description": "UUID laporan."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/regulatory-reports/5ec00000-0000-4000-8000-000000000007/finalize/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.regulatory_reports.finalize(\n    \"5ec00000-0000-4000-8000-000000000007\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.regulatoryReports.finalize(\"5ec00000-0000-4000-8000-000000000007\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.RegulatoryReports.Finalize(ctx, \"5ec00000-0000-4000-8000-000000000007\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.regulatoryReports().finalize_(\"5ec00000-0000-4000-8000-000000000007\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->regulatoryReports->finalize('5ec00000-0000-4000-8000-000000000007');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.regulatory_reports.finalize(\"5ec00000-0000-4000-8000-000000000007\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.RegulatoryReports.FinalizeAsync(\"5ec00000-0000-4000-8000-000000000007\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "Laporan selesai; xml_s3_key dan pdf_s3_key telah ditetapkan.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RegulatoryReportDetail"
                }
              }
            }
          },
          "400": {
            "description": "Validasi laporan gagal.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    },
                    "errors": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "field": {
                            "type": "string"
                          },
                          "message": {
                            "type": "string"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "Laporan tidak dalam status yang dapat difinalisasi.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/regulatory-reports/{report_uuid}/download-url/": {
      "get": {
        "summary": "Dapatkan URL unduhan laporan",
        "description": "Buat URL presigned untuk XML goAML atau PDF dari laporan yang telah difinalisasi.",
        "operationId": "get_regulatory_report_download_url",
        "x-didit-sdk": {
          "resource": "regulatory_reports",
          "method": "retrieve_download_url",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Regulatory Reports"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID organisasi."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID aplikasi."
          },
          {
            "name": "report_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "5ec00000-0000-4000-8000-000000000007"
            },
            "description": "UUID laporan."
          },
          {
            "name": "file",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "pdf",
                "xml"
              ],
              "default": "pdf"
            },
            "description": "File mana yang akan diunduh."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/regulatory-reports/5ec00000-0000-4000-8000-000000000007/download-url/?file=xml' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.regulatory_reports.retrieve_download_url(\n    \"5ec00000-0000-4000-8000-000000000007\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.regulatoryReports.retrieveDownloadUrl(\"5ec00000-0000-4000-8000-000000000007\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.RegulatoryReports.RetrieveDownloadURL(ctx, \"5ec00000-0000-4000-8000-000000000007\", didit.RegulatoryReportsRetrieveDownloadURLParams{})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.regulatoryReports().retrieveDownloadUrl(\"5ec00000-0000-4000-8000-000000000007\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->regulatoryReports->retrieveDownloadUrl('5ec00000-0000-4000-8000-000000000007');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.regulatory_reports.retrieve_download_url(\"5ec00000-0000-4000-8000-000000000007\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.RegulatoryReports.RetrieveDownloadUrlAsync(\"5ec00000-0000-4000-8000-000000000007\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "URL unduhan presigned.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "download_url": {
                      "type": "string",
                      "format": "uri"
                    },
                    "file": {
                      "type": "string",
                      "enum": [
                        "pdf",
                        "xml"
                      ]
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "Laporan belum selesai.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    },
                    "status": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/transactions/rules/": {
      "get": {
        "summary": "Mencantumkan daftar aturan",
        "description": "Mencantumkan daftar aturan pemantauan transaksi aplikasi: aturan kustom Anda ditambah preset pustaka apa pun yang telah Anda pasang. Filter berdasarkan sumber, kategori, mode, bundel, atau pencarian teks bebas; urutkan dengan `ordering` (run_count, approved_pct, reviewed_pct, declined_pct, latest_triggered_at, title, created_at, source, masing-masing dengan awalan opsional `-`).",
        "operationId": "listTransactionRules",
        "x-didit-sdk": {
          "resource": "transactions.rules",
          "method": "list",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Transactions"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "source",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "PRESET",
                "CUSTOM"
              ]
            },
            "description": "PRESET atau CUSTOM"
          },
          {
            "name": "category",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Filter berdasarkan kategori aturan"
          },
          {
            "name": "mode",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "ACTIVE",
                "DISABLED",
                "TEST"
              ]
            },
            "description": "ACTIVE, DISABLED, atau TEST"
          },
          {
            "name": "bundle",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Filter prasetel berdasarkan bundel"
          },
          {
            "name": "search",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Pencocokan yang tidak peka huruf besar/kecil terhadap judul dan deskripsi"
          },
          {
            "name": "ordering",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Kolom pengurutan yang dipisahkan dengan koma, default source,-run_count"
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            },
            "description": "Ukuran halaman"
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            },
            "description": "Offset halaman"
          }
        ],
        "responses": {
          "200": {
            "description": "Aturan terpaginasi.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "count": {
                      "type": "integer"
                    },
                    "next": {
                      "type": "string",
                      "nullable": true
                    },
                    "previous": {
                      "type": "string",
                      "nullable": true
                    },
                    "results": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/TransactionRuleDetail"
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/transactions/rules/?source=CUSTOM&ordering=-run_count' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nfor item in client.transactions.rules.list():\n    print(item)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nfor await (const item of didit.transactions.rules.list()) {\n  console.log(item);\n}"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\niter := client.Transactions.Rules.ListAutoPaging(ctx, didit.TransactionsRulesListParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nfor (var item : client.transactions().rules().list()) {\n    System.out.println(item);\n}"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\nforeach ($didit->transactions->rules->list() as $item) {\n    print_r($item->toArray());\n}"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.transactions.rules.list.auto_paging_each do |item|\n  puts item.to_h\nend"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.Transactions.Rules.ListAsync())\n{\n    Console.WriteLine(JsonSerializer.Serialize(item));\n}"
          }
        ]
      },
      "post": {
        "summary": "Buat aturan",
        "description": "Buat aturan pemantauan transaksi CUSTOM. Judul unik per aplikasi (duplikat -> 400). Tindakan `change_status` yang menargetkan `AWAITING_USER` harus menyertakan `workflow_id`. Aturan yang dibuat dalam mode ACTIVE langsung berlaku untuk transaksi baru - alur kerja yang disarankan adalah membuat dalam mode TEST, lakukan backtest, lalu alihkan mode ke ACTIVE. Untuk mengubah aturan pustaka, buat sebagai salinan: kirim definisi aturan pustaka dengan `metadata.based_on` (kunci pustakanya) dan `metadata.based_on_rule_uuid`.",
        "operationId": "createTransactionRule",
        "x-didit-sdk": {
          "resource": "transactions.rules",
          "method": "create",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Transactions"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TransactionRuleCreateRequest"
              },
              "example": {
                "title": "Structuring - inbound (custom)",
                "description": "20+ inbound EUR transfers, all under 10,000 EUR, 30 days",
                "category": "finance",
                "mode": "TEST",
                "evaluation_mode": "ALL",
                "scope": {
                  "transaction_types": [
                    "finance"
                  ],
                  "directions": [
                    "INBOUND"
                  ]
                },
                "conditions": [
                  {
                    "field": "currency",
                    "operator": "eq",
                    "value": "EUR"
                  },
                  {
                    "field": "amount",
                    "operator": "lt",
                    "value": 10000
                  }
                ],
                "aggregation": [
                  {
                    "metric": "count",
                    "operator": "gte",
                    "value": 20,
                    "window": "30d",
                    "filters": {
                      "direction": "INBOUND",
                      "transaction_type": "finance",
                      "subject_vendor_data": "__current__",
                      "currency": "EUR"
                    }
                  },
                  {
                    "metric": "max",
                    "field": "amount",
                    "operator": "lt",
                    "value": 10000,
                    "window": "30d",
                    "filters": {
                      "direction": "INBOUND",
                      "transaction_type": "finance",
                      "subject_vendor_data": "__current__",
                      "currency": "EUR"
                    }
                  }
                ],
                "actions": [
                  {
                    "type": "add_score",
                    "value": 35
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Aturan yang dibuat.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TransactionRuleDetail"
                }
              }
            }
          },
          "400": {
            "description": "Kesalahan validasi - judul duplikat, operator/metrik tidak dikenal, window salah format, arah cakupan tidak valid, atau AWAITING_USER tanpa workflow_id.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "title": [
                    "A rule with this name already exists."
                  ]
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://verification.didit.me/v3/transactions/rules/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"title\": \"Structuring - inbound (custom)\", \"description\": \"20+ inbound EUR transfers, all under 10,000 EUR, 30 days\", \"category\": \"finance\", \"mode\": \"TEST\", \"evaluation_mode\": \"ALL\", \"scope\": {\"transaction_types\": [\"finance\"], \"directions\": [\"INBOUND\"]}, \"conditions\": [{\"field\": \"currency\", \"operator\": \"eq\", \"value\": \"EUR\"}, {\"field\": \"amount\", \"operator\": \"lt\", \"value\": 10000}], \"aggregation\": [{\"metric\": \"count\", \"operator\": \"gte\", \"value\": 20, \"window\": \"30d\", \"filters\": {\"direction\": \"INBOUND\", \"transaction_type\": \"finance\", \"subject_vendor_data\": \"__current__\", \"currency\": \"EUR\"}}, {\"metric\": \"max\", \"field\": \"amount\", \"operator\": \"lt\", \"value\": 10000, \"window\": \"30d\", \"filters\": {\"direction\": \"INBOUND\", \"transaction_type\": \"finance\", \"subject_vendor_data\": \"__current__\", \"currency\": \"EUR\"}}], \"actions\": [{\"type\": \"add_score\", \"value\": 35}]}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.transactions.rules.create(\n    title=\"Structuring - inbound (custom)\",\n    description=\"20+ inbound EUR transfers, all under 10,000 EUR, 30 days\",\n    category=\"finance\",\n    mode=\"TEST\",\n    evaluation_mode=\"ALL\",\n    scope={\n        \"transaction_types\": [\"finance\"],\n        \"directions\": [\"INBOUND\"],\n    },\n    conditions=[{\n        \"field\": \"currency\",\n        \"operator\": \"eq\",\n        \"value\": \"EUR\",\n    }, {\n        \"field\": \"amount\",\n        \"operator\": \"lt\",\n        \"value\": 10000,\n    }],\n    aggregation=[{\n        \"metric\": \"count\",\n        \"operator\": \"gte\",\n        \"value\": 20.0,\n        \"window\": \"30d\",\n        \"filters\": {\"direction\": \"INBOUND\", \"transaction_type\": \"finance\", \"subject_vendor_data\": \"__current__\", \"currency\": \"EUR\"},\n    }, {\n        \"metric\": \"max\",\n        \"field\": \"amount\",\n        \"operator\": \"lt\",\n        \"value\": 10000.0,\n        \"window\": \"30d\",\n        \"filters\": {\"direction\": \"INBOUND\", \"transaction_type\": \"finance\", \"subject_vendor_data\": \"__current__\", \"currency\": \"EUR\"},\n    }],\n    actions=[{\n        \"type\": \"add_score\",\n        \"value\": 35,\n    }],\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.transactions.rules.create({\n  title: \"Structuring - inbound (custom)\",\n  description: \"20+ inbound EUR transfers, all under 10,000 EUR, 30 days\",\n  category: \"finance\",\n  mode: \"TEST\",\n  evaluation_mode: \"ALL\",\n  scope: {\n    transaction_types: [\"finance\"],\n    directions: [\"INBOUND\"],\n  },\n  conditions: [{\n    field: \"currency\",\n    operator: \"eq\",\n    value: \"EUR\",\n  }, {\n    field: \"amount\",\n    operator: \"lt\",\n    value: 10000,\n  }],\n  aggregation: [{\n    metric: \"count\",\n    operator: \"gte\",\n    value: 20.0,\n    window: \"30d\",\n    filters: { direction: \"INBOUND\", transaction_type: \"finance\", subject_vendor_data: \"__current__\", currency: \"EUR\" },\n  }, {\n    metric: \"max\",\n    field: \"amount\",\n    operator: \"lt\",\n    value: 10000.0,\n    window: \"30d\",\n    filters: { direction: \"INBOUND\", transaction_type: \"finance\", subject_vendor_data: \"__current__\", currency: \"EUR\" },\n  }],\n  actions: [{\n    type: \"add_score\",\n    value: 35,\n  }],\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Transactions.Rules.Create(ctx, didit.TransactionRuleCreateRequest{\n\tTitle:          \"Structuring - inbound (custom)\",\n\tDescription:    didit.String(\"20+ inbound EUR transfers, all under 10,000 EUR, 30 days\"),\n\tCategory:       \"finance\",\n\tMode:           \"TEST\",\n\tEvaluationMode: didit.Some(didit.TransactionRuleCreateRequestEvaluationMode(\"ALL\")),\n\tScope: didit.Some(didit.TransactionRuleScopeParam{\n\t\tTransactionTypes: didit.Some([]string{\"finance\"}),\n\t\tDirections:       didit.Some([]didit.TransactionRuleScopeDirections{\"INBOUND\"}),\n\t}),\n\tConditions: didit.Some([]didit.TransactionRuleConditionParam{{\n\t\tField:    \"currency\",\n\t\tOperator: \"eq\",\n\t\tValue:    didit.Some[any](\"EUR\"),\n\t}, {\n\t\tField:    \"amount\",\n\t\tOperator: \"lt\",\n\t\tValue:    didit.Some[any](10000),\n\t}}),\n\tAggregation: didit.Some([]didit.TransactionRuleAggregationParam{{\n\t\tMetric:   didit.Some(didit.TransactionRuleAggregationMetric(\"count\")),\n\t\tOperator: didit.Some(didit.TransactionRuleAggregationOperator(\"gte\")),\n\t\tValue:    20.0,\n\t\tWindow:   didit.String(\"30d\"),\n\t\tFilters:  didit.Some(map[string]any{\"direction\": \"INBOUND\", \"transaction_type\": \"finance\", \"subject_vendor_data\": \"__current__\", \"currency\": \"EUR\"}),\n\t}, {\n\t\tMetric:   didit.Some(didit.TransactionRuleAggregationMetric(\"max\")),\n\t\tField:    didit.String(\"amount\"),\n\t\tOperator: didit.Some(didit.TransactionRuleAggregationOperator(\"lt\")),\n\t\tValue:    10000.0,\n\t\tWindow:   didit.String(\"30d\"),\n\t\tFilters:  didit.Some(map[string]any{\"direction\": \"INBOUND\", \"transaction_type\": \"finance\", \"subject_vendor_data\": \"__current__\", \"currency\": \"EUR\"}),\n\t}}),\n\tActions: didit.Some([]didit.TransactionRuleActionParam{{\n\t\tType:  \"add_score\",\n\t\tValue: didit.Some[any](35),\n\t}}),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.List;\nimport java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.TransactionRuleAction;\nimport me.didit.types.TransactionRuleActionAddScore;\nimport me.didit.types.TransactionRuleAggregation;\nimport me.didit.types.TransactionRuleCondition;\nimport me.didit.types.TransactionRuleCreateRequest;\nimport me.didit.types.TransactionRuleScope;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.transactions().rules().create(TransactionRuleCreateRequest.builder()\n        .title(\"Structuring - inbound (custom)\")\n        .description(\"20+ inbound EUR transfers, all under 10,000 EUR, 30 days\")\n        .category(\"finance\")\n        .mode(TransactionRuleCreateRequest.Mode.of(\"TEST\"))\n        .evaluationMode(TransactionRuleCreateRequest.EvaluationMode.of(\"ALL\"))\n        .scope(TransactionRuleScope.builder()\n                .transactionTypes(List.of(\"finance\"))\n                .directions(List.of(TransactionRuleScope.Directions.of(\"INBOUND\")))\n                .build())\n        .conditions(List.of(\n                TransactionRuleCondition.builder()\n                        .field(\"currency\")\n                        .operator(TransactionRuleCondition.Operator.of(\"eq\"))\n                        .value(\"EUR\")\n                        .build(),\n                TransactionRuleCondition.builder()\n                        .field(\"amount\")\n                        .operator(TransactionRuleCondition.Operator.of(\"lt\"))\n                        .value(10000)\n                        .build()))\n        .aggregation(List.of(\n                TransactionRuleAggregation.builder()\n                        .metric(TransactionRuleAggregation.Metric.of(\"count\"))\n                        .operator(TransactionRuleAggregation.Operator.of(\"gte\"))\n                        .value(20.0)\n                        .window(\"30d\")\n                        .filters(Map.of(\"direction\", \"INBOUND\", \"transaction_type\", \"finance\", \"subject_vendor_data\", \"__current__\", \"currency\", \"EUR\"))\n                        .build(),\n                TransactionRuleAggregation.builder()\n                        .metric(TransactionRuleAggregation.Metric.of(\"max\"))\n                        .field(\"amount\")\n                        .operator(TransactionRuleAggregation.Operator.of(\"lt\"))\n                        .value(10000.0)\n                        .window(\"30d\")\n                        .filters(Map.of(\"direction\", \"INBOUND\", \"transaction_type\", \"finance\", \"subject_vendor_data\", \"__current__\", \"currency\", \"EUR\"))\n                        .build()))\n        .actions(List.of(TransactionRuleAction.ofAddScore(TransactionRuleActionAddScore.builder()\n                .type(TransactionRuleActionAddScore.Type.of(\"add_score\"))\n                .value(35L)\n                .build())))\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->transactions->rules->create([\n    'title' => 'Structuring - inbound (custom)',\n    'description' => '20+ inbound EUR transfers, all under 10,000 EUR, 30 days',\n    'category' => 'finance',\n    'mode' => 'TEST',\n    'evaluation_mode' => 'ALL',\n    'scope' => [\n        'transaction_types' => ['finance'],\n        'directions' => ['INBOUND'],\n    ],\n    'conditions' => [[\n        'field' => 'currency',\n        'operator' => 'eq',\n        'value' => 'EUR',\n    ], [\n        'field' => 'amount',\n        'operator' => 'lt',\n        'value' => 10000,\n    ]],\n    'aggregation' => [[\n        'metric' => 'count',\n        'operator' => 'gte',\n        'value' => 20.0,\n        'window' => '30d',\n        'filters' => ['direction' => 'INBOUND', 'transaction_type' => 'finance', 'subject_vendor_data' => '__current__', 'currency' => 'EUR'],\n    ], [\n        'metric' => 'max',\n        'field' => 'amount',\n        'operator' => 'lt',\n        'value' => 10000.0,\n        'window' => '30d',\n        'filters' => ['direction' => 'INBOUND', 'transaction_type' => 'finance', 'subject_vendor_data' => '__current__', 'currency' => 'EUR'],\n    ]],\n    'actions' => [[\n        'type' => 'add_score',\n        'value' => 35,\n    ]],\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.transactions.rules.create(\n  title: \"Structuring - inbound (custom)\",\n  description: \"20+ inbound EUR transfers, all under 10,000 EUR, 30 days\",\n  category: \"finance\",\n  mode: \"TEST\",\n  evaluation_mode: \"ALL\",\n  scope: {\n    transaction_types: [\"finance\"],\n    directions: [\"INBOUND\"],\n  },\n  conditions: [{\n    field: \"currency\",\n    operator: \"eq\",\n    value: \"EUR\",\n  }, {\n    field: \"amount\",\n    operator: \"lt\",\n    value: 10000,\n  }],\n  aggregation: [{\n    metric: \"count\",\n    operator: \"gte\",\n    value: 20.0,\n    window: \"30d\",\n    filters: { direction: \"INBOUND\", transaction_type: \"finance\", subject_vendor_data: \"__current__\", currency: \"EUR\" },\n  }, {\n    metric: \"max\",\n    field: \"amount\",\n    operator: \"lt\",\n    value: 10000.0,\n    window: \"30d\",\n    filters: { direction: \"INBOUND\", transaction_type: \"finance\", subject_vendor_data: \"__current__\", currency: \"EUR\" },\n  }],\n  actions: [{\n    type: \"add_score\",\n    value: 35,\n  }]\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Transactions.Rules.CreateAsync(new TransactionRuleCreateRequest\n{\n    Title = \"Structuring - inbound (custom)\",\n    Description = \"20+ inbound EUR transfers, all under 10,000 EUR, 30 days\",\n    Category = \"finance\",\n    Mode = \"TEST\",\n    EvaluationMode = new TransactionRuleCreateRequestEvaluationMode(\"ALL\"),\n    Scope = new TransactionRuleScope\n    {\n        TransactionTypes = new string[] { \"finance\" },\n        Directions = new TransactionRuleScopeDirections[] { \"INBOUND\" },\n    },\n    Conditions = new TransactionRuleCondition[]\n    {\n        new()\n        {\n            Field = \"currency\",\n            Operator = \"eq\",\n            Value = \"EUR\",\n        },\n        new()\n        {\n            Field = \"amount\",\n            Operator = \"lt\",\n            Value = 10000,\n        },\n    },\n    Aggregation = new TransactionRuleAggregation[]\n    {\n        new()\n        {\n            Metric = new TransactionRuleAggregationMetric(\"count\"),\n            Operator = new TransactionRuleAggregationOperator(\"gte\"),\n            Value = 20.0,\n            Window = \"30d\",\n            Filters = new Dictionary<string, object> { [\"direction\"] = \"INBOUND\", [\"transaction_type\"] = \"finance\", [\"subject_vendor_data\"] = \"__current__\", [\"currency\"] = \"EUR\" },\n        },\n        new()\n        {\n            Metric = new TransactionRuleAggregationMetric(\"max\"),\n            Field = \"amount\",\n            Operator = new TransactionRuleAggregationOperator(\"lt\"),\n            Value = 10000.0,\n            Window = \"30d\",\n            Filters = new Dictionary<string, object> { [\"direction\"] = \"INBOUND\", [\"transaction_type\"] = \"finance\", [\"subject_vendor_data\"] = \"__current__\", [\"currency\"] = \"EUR\" },\n        },\n    },\n    Actions = new TransactionRuleAction[]\n    {\n        new()\n        {\n            Type = new TransactionRuleActionType(\"add_score\"),\n            Value = 35,\n        },\n    },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/transactions/rules/{rule_uuid}/": {
      "parameters": [
        {
          "name": "rule_uuid",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string",
            "format": "uuid"
          },
          "description": "UUID aturan dari operasi list atau create."
        }
      ],
      "get": {
        "summary": "Dapatkan aturan",
        "description": "Ambil satu aturan beserta konfigurasi lengkap dan penghitung eksekusinya.",
        "operationId": "getTransactionRule",
        "x-didit-sdk": {
          "resource": "transactions.rules",
          "method": "retrieve",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Transactions"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Aturan.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TransactionRuleDetail"
                }
              }
            }
          },
          "404": {
            "description": "Tidak ada aturan seperti itu pada aplikasi ini.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/transactions/rules/RULE_UUID/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.transactions.rules.retrieve(\n    \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.transactions.rules.retrieve(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Transactions.Rules.Retrieve(ctx, \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.transactions().rules().retrieve(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->transactions->rules->retrieve('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.transactions.rules.retrieve(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Transactions.Rules.RetrieveAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      },
      "patch": {
        "summary": "Perbarui aturan",
        "description": "Perbarui aturan secara parsial. Aturan kustom menerima semua kolom konfigurasi. Aturan pustaka (PRESET) hanya menerima `mode` - gunakan untuk mengaktifkan, menonaktifkan, atau mengalihkan preset ke TEST; kolom lain akan mengembalikan 400, karena Didit memelihara aturan pustaka dan menerapkan pembaruannya secara otomatis. Untuk mengubah ketentuan aturan pustaka, buat salinan kustom dengan `POST /v3/transactions/rules/` menggunakan definisi aturan pustaka serta `metadata.based_on` (kunci pustaka) dan `metadata.based_on_rule_uuid`, lalu nonaktifkan aturan pustaka dengan `mode: DISABLED` agar transaksi tidak memicu alert dua kali. Salinan terpasang dari aturan pustaka yang ditahan akan dinonaktifkan: menyetel `mode`-nya ke nilai selain `DISABLED` akan menghasilkan 400 (\"Aturan pustaka ini belum dapat dijalankan: kondisinya membaca data yang tidak dapat dievaluasi oleh mesin aturan.\").",
        "operationId": "updateTransactionRule",
        "x-didit-sdk": {
          "resource": "transactions.rules",
          "method": "update",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Transactions"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TransactionRuleUpdateRequest"
              },
              "example": {
                "mode": "ACTIVE"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Aturan yang diperbarui.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TransactionRuleDetail"
                }
              }
            }
          },
          "400": {
            "description": "Kesalahan validasi, kolom non-mode pada aturan pustaka, atau mode selain DISABLED pada aturan pustaka yang ditahan.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X PATCH 'https://verification.didit.me/v3/transactions/rules/RULE_UUID/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"mode\": \"ACTIVE\"}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.transactions.rules.update(\n    \"11111111-2222-3333-4444-555555555555\",\n    mode=\"ACTIVE\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.transactions.rules.update(\"11111111-2222-3333-4444-555555555555\", {\n  mode: \"ACTIVE\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Transactions.Rules.Update(ctx, \"11111111-2222-3333-4444-555555555555\", didit.TransactionRuleUpdateRequest{\n\tMode: didit.Some(didit.TransactionRuleUpdateRequestMode(\"ACTIVE\")),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.TransactionRuleUpdateRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.transactions().rules().update(\"11111111-2222-3333-4444-555555555555\", TransactionRuleUpdateRequest.builder()\n        .mode(TransactionRuleUpdateRequest.Mode.of(\"ACTIVE\"))\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->transactions->rules->update('11111111-2222-3333-4444-555555555555', [\n    'mode' => 'ACTIVE',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.transactions.rules.update(\n  \"11111111-2222-3333-4444-555555555555\",\n  mode: \"ACTIVE\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Transactions.Rules.UpdateAsync(\"11111111-2222-3333-4444-555555555555\", new TransactionRuleUpdateRequest\n{\n    Mode = new TransactionRuleUpdateRequestMode(\"ACTIVE\"),\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      },
      "delete": {
        "summary": "Hapus aturan",
        "description": "Hapus aturan CUSTOM. Penghapusan bersifat langsung dan permanen: aturan berhenti mengevaluasi transaksi baru dan menghilang dari daftar, sedangkan eksekusi aturan sebelumnya pada transaksi yang telah dievaluasi tetap mempertahankan hasil yang tercatat. Aturan pustaka tidak dapat dihapus - uninstal aturan tersebut melalui endpoint penginstalan (aturan selalu dapat diinstal ulang dari pustaka).",
        "operationId": "deleteTransactionRule",
        "x-didit-sdk": {
          "resource": "transactions.rules",
          "method": "delete",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Transactions"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "204": {
            "description": "Dihapus."
          },
          "400": {
            "description": "Aturan ini adalah preset pustaka - hapus instalasi sebagai gantinya.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "detail": "Library rules cannot be deleted. Uninstall them via the rules install endpoint instead."
                }
              }
            }
          },
          "404": {
            "description": "Tidak ada aturan seperti itu pada aplikasi ini.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X DELETE 'https://verification.didit.me/v3/transactions/rules/RULE_UUID/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nclient.transactions.rules.delete(\n    \"11111111-2222-3333-4444-555555555555\",\n)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nawait didit.transactions.rules.delete(\"11111111-2222-3333-4444-555555555555\");"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nif err := client.Transactions.Rules.Delete(ctx, \"11111111-2222-3333-4444-555555555555\"); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nclient.transactions().rules().delete(\"11111111-2222-3333-4444-555555555555\");"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$didit->transactions->rules->delete('11111111-2222-3333-4444-555555555555');"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.transactions.rules.delete(\"11111111-2222-3333-4444-555555555555\")"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nawait client.Transactions.Rules.DeleteAsync(\"11111111-2222-3333-4444-555555555555\");"
          }
        ]
      }
    },
    "/v3/transactions/rules/backtest/": {
      "post": {
        "summary": "Konfigurasi aturan backtest",
        "description": "Evaluasi konfigurasi aturan hipotetis terhadap transaksi terkini Anda (paling baru terlebih dahulu, hingga batas backtest) tanpa membuat aturan atau mengubah transaksi apa pun. Gunakan ini sebelum mengaktifkan aturan untuk melihat seberapa sering aturan tersebut cocok dan berapa banyak subjek yang terpengaruh.",
        "operationId": "backtestTransactionRules",
        "x-didit-sdk": {
          "resource": "transactions.rules",
          "method": "backtest",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Transactions"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TransactionRuleBacktestRequest"
              },
              "example": {
                "conditions": [
                  {
                    "field": "currency",
                    "operator": "eq",
                    "value": "EUR"
                  },
                  {
                    "field": "amount",
                    "operator": "lt",
                    "value": 10000
                  }
                ],
                "aggregation": [
                  {
                    "metric": "count",
                    "operator": "gte",
                    "value": 20,
                    "window": "30d",
                    "filters": {
                      "direction": "INBOUND",
                      "transaction_type": "finance",
                      "subject_vendor_data": "__current__",
                      "currency": "EUR"
                    }
                  },
                  {
                    "metric": "max",
                    "field": "amount",
                    "operator": "lt",
                    "value": 10000,
                    "window": "30d",
                    "filters": {
                      "direction": "INBOUND",
                      "transaction_type": "finance",
                      "subject_vendor_data": "__current__",
                      "currency": "EUR"
                    }
                  }
                ],
                "evaluation_mode": "ALL",
                "scope": {
                  "transaction_types": [
                    "finance"
                  ],
                  "directions": [
                    "INBOUND"
                  ]
                },
                "period_days": 90
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Statistik backtest.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TransactionRuleBacktestResult"
                },
                "example": {
                  "evaluated": 4820,
                  "matched": 12,
                  "affected_entities": 4,
                  "period_days": 90
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://verification.didit.me/v3/transactions/rules/backtest/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"conditions\": [{\"field\": \"currency\", \"operator\": \"eq\", \"value\": \"EUR\"}, {\"field\": \"amount\", \"operator\": \"lt\", \"value\": 10000}], \"aggregation\": [{\"metric\": \"count\", \"operator\": \"gte\", \"value\": 20, \"window\": \"30d\", \"filters\": {\"direction\": \"INBOUND\", \"transaction_type\": \"finance\", \"subject_vendor_data\": \"__current__\", \"currency\": \"EUR\"}}, {\"metric\": \"max\", \"field\": \"amount\", \"operator\": \"lt\", \"value\": 10000, \"window\": \"30d\", \"filters\": {\"direction\": \"INBOUND\", \"transaction_type\": \"finance\", \"subject_vendor_data\": \"__current__\", \"currency\": \"EUR\"}}], \"evaluation_mode\": \"ALL\", \"scope\": {\"transaction_types\": [\"finance\"], \"directions\": [\"INBOUND\"]}, \"period_days\": 90}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.transactions.rules.backtest(\n    conditions=[{\n        \"field\": \"currency\",\n        \"operator\": \"eq\",\n        \"value\": \"EUR\",\n    }, {\n        \"field\": \"amount\",\n        \"operator\": \"lt\",\n        \"value\": 10000,\n    }],\n    aggregation=[{\n        \"metric\": \"count\",\n        \"operator\": \"gte\",\n        \"value\": 20.0,\n        \"window\": \"30d\",\n        \"filters\": {\"direction\": \"INBOUND\", \"transaction_type\": \"finance\", \"subject_vendor_data\": \"__current__\", \"currency\": \"EUR\"},\n    }, {\n        \"metric\": \"max\",\n        \"field\": \"amount\",\n        \"operator\": \"lt\",\n        \"value\": 10000.0,\n        \"window\": \"30d\",\n        \"filters\": {\"direction\": \"INBOUND\", \"transaction_type\": \"finance\", \"subject_vendor_data\": \"__current__\", \"currency\": \"EUR\"},\n    }],\n    evaluation_mode=\"ALL\",\n    scope={\n        \"transaction_types\": [\"finance\"],\n        \"directions\": [\"INBOUND\"],\n    },\n    period_days=90,\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.transactions.rules.backtest({\n  conditions: [{\n    field: \"currency\",\n    operator: \"eq\",\n    value: \"EUR\",\n  }, {\n    field: \"amount\",\n    operator: \"lt\",\n    value: 10000,\n  }],\n  aggregation: [{\n    metric: \"count\",\n    operator: \"gte\",\n    value: 20.0,\n    window: \"30d\",\n    filters: { direction: \"INBOUND\", transaction_type: \"finance\", subject_vendor_data: \"__current__\", currency: \"EUR\" },\n  }, {\n    metric: \"max\",\n    field: \"amount\",\n    operator: \"lt\",\n    value: 10000.0,\n    window: \"30d\",\n    filters: { direction: \"INBOUND\", transaction_type: \"finance\", subject_vendor_data: \"__current__\", currency: \"EUR\" },\n  }],\n  evaluation_mode: \"ALL\",\n  scope: {\n    transaction_types: [\"finance\"],\n    directions: [\"INBOUND\"],\n  },\n  period_days: 90,\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Transactions.Rules.Backtest(ctx, didit.TransactionRuleBacktestRequest{\n\tConditions: didit.Some([]didit.TransactionRuleConditionParam{{\n\t\tField:    \"currency\",\n\t\tOperator: \"eq\",\n\t\tValue:    didit.Some[any](\"EUR\"),\n\t}, {\n\t\tField:    \"amount\",\n\t\tOperator: \"lt\",\n\t\tValue:    didit.Some[any](10000),\n\t}}),\n\tAggregation: didit.Some([]didit.TransactionRuleAggregationParam{{\n\t\tMetric:   didit.Some(didit.TransactionRuleAggregationMetric(\"count\")),\n\t\tOperator: didit.Some(didit.TransactionRuleAggregationOperator(\"gte\")),\n\t\tValue:    20.0,\n\t\tWindow:   didit.String(\"30d\"),\n\t\tFilters:  didit.Some(map[string]any{\"direction\": \"INBOUND\", \"transaction_type\": \"finance\", \"subject_vendor_data\": \"__current__\", \"currency\": \"EUR\"}),\n\t}, {\n\t\tMetric:   didit.Some(didit.TransactionRuleAggregationMetric(\"max\")),\n\t\tField:    didit.String(\"amount\"),\n\t\tOperator: didit.Some(didit.TransactionRuleAggregationOperator(\"lt\")),\n\t\tValue:    10000.0,\n\t\tWindow:   didit.String(\"30d\"),\n\t\tFilters:  didit.Some(map[string]any{\"direction\": \"INBOUND\", \"transaction_type\": \"finance\", \"subject_vendor_data\": \"__current__\", \"currency\": \"EUR\"}),\n\t}}),\n\tEvaluationMode: didit.Some(didit.TransactionRuleBacktestRequestEvaluationMode(\"ALL\")),\n\tScope: didit.Some(didit.TransactionRuleScopeParam{\n\t\tTransactionTypes: didit.Some([]string{\"finance\"}),\n\t\tDirections:       didit.Some([]didit.TransactionRuleScopeDirections{\"INBOUND\"}),\n\t}),\n\tPeriodDays: didit.Int(90),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.List;\nimport java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.TransactionRuleAggregation;\nimport me.didit.types.TransactionRuleBacktestRequest;\nimport me.didit.types.TransactionRuleCondition;\nimport me.didit.types.TransactionRuleScope;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.transactions().rules().backtest(TransactionRuleBacktestRequest.builder()\n        .conditions(List.of(\n                TransactionRuleCondition.builder()\n                        .field(\"currency\")\n                        .operator(TransactionRuleCondition.Operator.of(\"eq\"))\n                        .value(\"EUR\")\n                        .build(),\n                TransactionRuleCondition.builder()\n                        .field(\"amount\")\n                        .operator(TransactionRuleCondition.Operator.of(\"lt\"))\n                        .value(10000)\n                        .build()))\n        .aggregation(List.of(\n                TransactionRuleAggregation.builder()\n                        .metric(TransactionRuleAggregation.Metric.of(\"count\"))\n                        .operator(TransactionRuleAggregation.Operator.of(\"gte\"))\n                        .value(20.0)\n                        .window(\"30d\")\n                        .filters(Map.of(\"direction\", \"INBOUND\", \"transaction_type\", \"finance\", \"subject_vendor_data\", \"__current__\", \"currency\", \"EUR\"))\n                        .build(),\n                TransactionRuleAggregation.builder()\n                        .metric(TransactionRuleAggregation.Metric.of(\"max\"))\n                        .field(\"amount\")\n                        .operator(TransactionRuleAggregation.Operator.of(\"lt\"))\n                        .value(10000.0)\n                        .window(\"30d\")\n                        .filters(Map.of(\"direction\", \"INBOUND\", \"transaction_type\", \"finance\", \"subject_vendor_data\", \"__current__\", \"currency\", \"EUR\"))\n                        .build()))\n        .evaluationMode(TransactionRuleBacktestRequest.EvaluationMode.of(\"ALL\"))\n        .scope(TransactionRuleScope.builder()\n                .transactionTypes(List.of(\"finance\"))\n                .directions(List.of(TransactionRuleScope.Directions.of(\"INBOUND\")))\n                .build())\n        .periodDays(90L)\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->transactions->rules->backtest([\n    'conditions' => [[\n        'field' => 'currency',\n        'operator' => 'eq',\n        'value' => 'EUR',\n    ], [\n        'field' => 'amount',\n        'operator' => 'lt',\n        'value' => 10000,\n    ]],\n    'aggregation' => [[\n        'metric' => 'count',\n        'operator' => 'gte',\n        'value' => 20.0,\n        'window' => '30d',\n        'filters' => ['direction' => 'INBOUND', 'transaction_type' => 'finance', 'subject_vendor_data' => '__current__', 'currency' => 'EUR'],\n    ], [\n        'metric' => 'max',\n        'field' => 'amount',\n        'operator' => 'lt',\n        'value' => 10000.0,\n        'window' => '30d',\n        'filters' => ['direction' => 'INBOUND', 'transaction_type' => 'finance', 'subject_vendor_data' => '__current__', 'currency' => 'EUR'],\n    ]],\n    'evaluation_mode' => 'ALL',\n    'scope' => [\n        'transaction_types' => ['finance'],\n        'directions' => ['INBOUND'],\n    ],\n    'period_days' => 90,\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.transactions.rules.backtest(\n  conditions: [{\n    field: \"currency\",\n    operator: \"eq\",\n    value: \"EUR\",\n  }, {\n    field: \"amount\",\n    operator: \"lt\",\n    value: 10000,\n  }],\n  aggregation: [{\n    metric: \"count\",\n    operator: \"gte\",\n    value: 20.0,\n    window: \"30d\",\n    filters: { direction: \"INBOUND\", transaction_type: \"finance\", subject_vendor_data: \"__current__\", currency: \"EUR\" },\n  }, {\n    metric: \"max\",\n    field: \"amount\",\n    operator: \"lt\",\n    value: 10000.0,\n    window: \"30d\",\n    filters: { direction: \"INBOUND\", transaction_type: \"finance\", subject_vendor_data: \"__current__\", currency: \"EUR\" },\n  }],\n  evaluation_mode: \"ALL\",\n  scope: {\n    transaction_types: [\"finance\"],\n    directions: [\"INBOUND\"],\n  },\n  period_days: 90\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Transactions.Rules.BacktestAsync(new TransactionRuleBacktestRequest\n{\n    Conditions = new TransactionRuleCondition[]\n    {\n        new()\n        {\n            Field = \"currency\",\n            Operator = \"eq\",\n            Value = \"EUR\",\n        },\n        new()\n        {\n            Field = \"amount\",\n            Operator = \"lt\",\n            Value = 10000,\n        },\n    },\n    Aggregation = new TransactionRuleAggregation[]\n    {\n        new()\n        {\n            Metric = new TransactionRuleAggregationMetric(\"count\"),\n            Operator = new TransactionRuleAggregationOperator(\"gte\"),\n            Value = 20.0,\n            Window = \"30d\",\n            Filters = new Dictionary<string, object> { [\"direction\"] = \"INBOUND\", [\"transaction_type\"] = \"finance\", [\"subject_vendor_data\"] = \"__current__\", [\"currency\"] = \"EUR\" },\n        },\n        new()\n        {\n            Metric = new TransactionRuleAggregationMetric(\"max\"),\n            Field = \"amount\",\n            Operator = new TransactionRuleAggregationOperator(\"lt\"),\n            Value = 10000.0,\n            Window = \"30d\",\n            Filters = new Dictionary<string, object> { [\"direction\"] = \"INBOUND\", [\"transaction_type\"] = \"finance\", [\"subject_vendor_data\"] = \"__current__\", [\"currency\"] = \"EUR\" },\n        },\n    },\n    EvaluationMode = new TransactionRuleBacktestRequestEvaluationMode(\"ALL\"),\n    Scope = new TransactionRuleScope\n    {\n        TransactionTypes = new string[] { \"finance\" },\n        Directions = new TransactionRuleScopeDirections[] { \"INBOUND\" },\n    },\n    PeriodDays = 90,\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/transactions/rules/library/": {
      "get": {
        "summary": "Mencantumkan daftar pustaka aturan",
        "description": "Jelajahi pustaka aturan preset lengkap (150+ aturan) dengan konfigurasi lengkap setiap entri dan tanda `is_installed` untuk aplikasi ini. Filter berdasarkan bundle, kategori, atau pencarian teks bebas. Aturan pustaka yang kondisinya membaca data yang belum dapat dievaluasi oleh mesin aturan akan ditahan hingga dapat dijalankan. Aturan yang ditahan tidak dicantumkan.",
        "operationId": "listTransactionRuleLibrary",
        "x-didit-sdk": {
          "resource": "transactions.rules",
          "method": "list_library",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Transactions"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "bundle",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Filter berdasarkan bundel, misalnya finance, aml_ctf, crypto_monitoring, travel_rule"
          },
          {
            "name": "category",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Filter berdasarkan kategori"
          },
          {
            "name": "search",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Pencocokan yang tidak peka huruf besar/kecil terhadap judul dan deskripsi"
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            },
            "description": "Ukuran halaman"
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            },
            "description": "Offset halaman"
          }
        ],
        "responses": {
          "200": {
            "description": "Entri pustaka berpaginasi.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "count": {
                      "type": "integer"
                    },
                    "next": {
                      "type": "string",
                      "nullable": true
                    },
                    "previous": {
                      "type": "string",
                      "nullable": true
                    },
                    "results": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/TransactionRuleLibraryEntry"
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/transactions/rules/library/?bundle=finance' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nfor item in client.transactions.rules.list_library():\n    print(item)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nfor await (const item of didit.transactions.rules.listLibrary()) {\n  console.log(item);\n}"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\niter := client.Transactions.Rules.ListLibraryAutoPaging(ctx, didit.TransactionsRulesListLibraryParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nfor (var item : client.transactions().rules().listLibrary()) {\n    System.out.println(item);\n}"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\nforeach ($didit->transactions->rules->listLibrary() as $item) {\n    print_r($item->toArray());\n}"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.transactions.rules.list_library.auto_paging_each do |item|\n  puts item.to_h\nend"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.Transactions.Rules.ListLibraryAsync())\n{\n    Console.WriteLine(JsonSerializer.Serialize(item));\n}"
          }
        ]
      }
    },
    "/v3/transactions/rules/install/": {
      "post": {
        "summary": "Instal aturan pustaka",
        "description": "Instal satu atau beberapa preset ke aplikasi, berdasarkan `library_keys` atau seluruh `bundle`. Preset yang terinstal langsung aktif saat pemantauan transaksi aktif, dan dinonaktifkan jika tidak; kunci yang sudah terinstal dilewati. Aturan pustaka yang kondisinya membaca data yang belum dapat dievaluasi oleh mesin aturan akan ditahan hingga dapat dijalankan. Permintaan yang menyebutkan salah satunya di `library_keys` menghasilkan respons 400 dan tidak menginstal apa pun (\"These library rules cannot run yet: their conditions read data the rules engine cannot evaluate.\" diikuti oleh kunci-kuncinya), dan penginstalan `bundle` melewatinya. Aturan yang ditahan akan aktif kembali dengan sendirinya setelah kondisinya dapat dievaluasi. Entri `library_keys` yang tidak ada di pustaka dilewati, bukan ditolak.",
        "operationId": "installTransactionRuleLibrary",
        "x-didit-sdk": {
          "resource": "transactions.rules",
          "method": "install_library",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Transactions"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TransactionRuleInstallRequest"
              },
              "example": {
                "library_keys": [
                  "structuring-inbound",
                  "structuring-outbound"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Apa yang diinstal.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TransactionRuleInstallResult"
                },
                "example": {
                  "installed_library_keys": [
                    "structuring-inbound",
                    "structuring-outbound"
                  ],
                  "installed_count": 2
                }
              }
            }
          },
          "400": {
            "description": "Baik library_keys maupun bundle tidak diberikan, `library_keys` bukan berupa list, atau entri `library_keys` ditahan. Entri yang tidak dikenal dilewati dan memberikan respons 200 tanpanya.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://verification.didit.me/v3/transactions/rules/install/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"library_keys\": [\"structuring-inbound\", \"structuring-outbound\"]}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.transactions.rules.install_library(\n    library_keys=[\"structuring-inbound\", \"structuring-outbound\"],\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.transactions.rules.installLibrary({\n  library_keys: [\"structuring-inbound\", \"structuring-outbound\"],\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Transactions.Rules.InstallLibrary(ctx, didit.TransactionRuleInstallRequest{\n\tLibraryKeys: didit.Some([]string{\"structuring-inbound\", \"structuring-outbound\"}),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.List;\nimport me.didit.Didit;\nimport me.didit.types.TransactionRuleInstallRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.transactions().rules().installLibrary(TransactionRuleInstallRequest.builder()\n        .libraryKeys(List.of(\"structuring-inbound\", \"structuring-outbound\"))\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->transactions->rules->installLibrary([\n    'library_keys' => ['structuring-inbound', 'structuring-outbound'],\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.transactions.rules.install_library(library_keys: [\"structuring-inbound\", \"structuring-outbound\"])\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Transactions.Rules.InstallLibraryAsync(new TransactionRuleInstallRequest\n{\n    LibraryKeys = new string[] { \"structuring-inbound\", \"structuring-outbound\" },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      },
      "delete": {
        "summary": "Copot aturan pustaka",
        "description": "Hapus preset terinstal dari aplikasi, berdasarkan `library_keys` atau seluruh `bundle`. Preset yang di-uninstal akan segera berhenti mengevaluasi dan dapat diinstal ulang dari pustaka kapan saja.",
        "operationId": "uninstallTransactionRuleLibrary",
        "x-didit-sdk": {
          "resource": "transactions.rules",
          "method": "uninstall_library",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Transactions"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TransactionRuleInstallRequest"
              },
              "example": {
                "bundle": "responsible_gaming"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Berapa banyak preset yang dihapus.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TransactionRuleInstallResult"
                },
                "example": {
                  "uninstalled_count": 5
                }
              }
            }
          },
          "400": {
            "description": "Baik library_keys maupun bundle tidak diberikan.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X DELETE 'https://verification.didit.me/v3/transactions/rules/install/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"bundle\": \"responsible_gaming\"}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.transactions.rules.uninstall_library(\n    bundle=\"responsible_gaming\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.transactions.rules.uninstallLibrary({\n  bundle: \"responsible_gaming\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Transactions.Rules.UninstallLibrary(ctx, didit.TransactionRuleInstallRequest{\n\tBundle: didit.String(\"responsible_gaming\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.TransactionRuleInstallRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.transactions().rules().uninstallLibrary(TransactionRuleInstallRequest.builder()\n        .bundle(\"responsible_gaming\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->transactions->rules->uninstallLibrary([\n    'bundle' => 'responsible_gaming',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.transactions.rules.uninstall_library(bundle: \"responsible_gaming\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Transactions.Rules.UninstallLibraryAsync(new TransactionRuleInstallRequest\n{\n    Bundle = \"responsible_gaming\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/networks/": {
      "get": {
        "summary": "Mencantumkan jaringan",
        "description": "Mencantumkan jaringan penipuan yang terdeteksi dalam organisasi aplikasi ini, dengan risiko tertinggi di urutan pertama secara default. Secara default jaringan yang diabaikan tidak disertakan; teruskan status untuk menyertakannya. Aplikasi sandbox tidak pernah memiliki jaringan: pengelompokan (clustering) mengecualikan data sandbox sepenuhnya. Setiap respons memuat `sharing_mode` organisasi dan apakah sinyal lintas organisasi berlaku untuknya (`cross_org_available`, `cross_org_unavailable_reason`). `kpis` mengagregasi jaringan yang cocok dengan filter Anda dan `counts` mengagregasi setiap jaringan yang dapat dilihat aplikasi; teruskan `summary=false` untuk melewati keduanya saat Anda hanya memerlukan halaman tersebut. Memerlukan kunci API akses penuh, atau `list:networks` untuk anggota konsol.",
        "operationId": "list_networks",
        "x-didit-sdk": {
          "resource": "networks",
          "method": "list",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Networks"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID organisasi."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID aplikasi."
          },
          {
            "name": "status",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Status yang dipisahkan dengan koma untuk disertakan: active,in_review,resolved,dismissed. Jangan sertakan untuk mengecualikan dismissed."
          },
          {
            "name": "scope",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "identity",
                "transactions"
              ]
            },
            "description": "`transactions` mempertahankan jaringan yang semua anggotanya adalah pihak transaksi; `identity` mempertahankan semua jaringan lainnya. Jangan sertakan untuk keduanya. Ini juga mempersempit `counts.views` dan `counts.facets`. Nilai lainnya akan mengembalikan 400."
          },
          {
            "name": "signal_type",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Jenis sinyal yang dipisahkan dengan koma: ip_address,device,face,document_number,phone,email,address."
          },
          {
            "name": "pattern_type",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Jenis pola yang dipisahkan dengan koma, misalnya exact_same_device,same_email."
          },
          {
            "name": "risk_band",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Rentang yang dipisahkan koma: low,medium,high."
          },
          {
            "name": "min_size",
            "in": "query",
            "schema": {
              "type": "integer"
            },
            "description": "Jumlah anggota minimum."
          },
          {
            "name": "max_size",
            "in": "query",
            "schema": {
              "type": "integer"
            },
            "description": "Jumlah anggota maksimum."
          },
          {
            "name": "assignee",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Penerima tugas yang dipisahkan koma: `unassigned`, email anggota (pencocokan tidak peka huruf besar/kecil), atau `me` untuk anggota konsol pemanggil. Jaringan cocok dengan nilai apa pun. `me` memerlukan token anggota konsol: kunci API menghasilkan 400 `{\"assignee\": [\"\\\"me\\\" needs a user token; an API key has no assignee identity.\"]}`."
          },
          {
            "name": "priority",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Prioritas yang dipisahkan dengan koma: `low`, `medium`, `high`, atau `none` untuk jaringan tanpa prioritas. Nilai lainnya mengembalikan 400 `{\"priority\": \"Unknown priority: <values>.\"}`."
          },
          {
            "name": "risk_min",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "maximum": 100
            },
            "description": "Skor risiko minimum, bilangan bulat dari 0 hingga 100. Nilai yang bukan bilangan bulat mengembalikan 400 `{\"risk_min\": \"Use a whole number from 0 to 100.\"}`."
          },
          {
            "name": "has_case",
            "in": "query",
            "schema": {
              "type": "boolean"
            },
            "description": "`true` mempertahankan jaringan tempat aplikasi Anda membuka kasus, `false` untuk yang lainnya. Nilai lainnya akan diabaikan."
          },
          {
            "name": "date_from",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date"
            },
            "description": "Batas bawah pada last_activity_at (tanggal atau tanggal-waktu ISO 8601)."
          },
          {
            "name": "date_to",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date"
            },
            "description": "Batas atas untuk first_activity_at (tanggal atau datetime ISO 8601)."
          },
          {
            "name": "q",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Pencarian teks bebas di seluruh nama jaringan, nama anggota, network_id (N-0001), dan token pattern_type yang tepat."
          },
          {
            "name": "ordering",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Salah satu dari risk_score, -risk_score, last_activity_at, -last_activity_at, first_activity_at, -first_activity_at, network_number, -network_number. Defaultnya adalah -risk_score,-last_activity_at."
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 100,
              "minimum": 1,
              "maximum": 500
            },
            "description": "Ukuran halaman, 1-500. Nilai default-nya 100."
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 0,
              "minimum": 0
            },
            "description": "Offset berbasis nol dari rekaman pertama."
          },
          {
            "name": "summary",
            "in": "query",
            "schema": {
              "type": "boolean",
              "default": true
            },
            "description": "`false` hanya mengembalikan halaman beserta `count`-nya, tanpa `kpis` dan `counts`. Default-nya adalah `true`. Nilai apa pun selain `true` atau `false` akan mengembalikan 400."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/networks/?status=active,in_review&ordering=-risk_score' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nfor item in client.networks.list():\n    print(item)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nfor await (const item of didit.networks.list()) {\n  console.log(item);\n}"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\niter := client.Networks.ListAutoPaging(ctx, didit.NetworksListParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nfor (var item : client.networks().list()) {\n    System.out.println(item);\n}"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\nforeach ($didit->networks->list() as $item) {\n    print_r($item->toArray());\n}"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\ndidit.networks.list.auto_paging_each do |item|\n  puts item.to_h\nend"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.Networks.ListAsync())\n{\n    Console.WriteLine(JsonSerializer.Serialize(item));\n}"
          }
        ],
        "responses": {
          "200": {
            "description": "Daftar jaringan berpaginasi, dengan mode berbagi organisasi dan ketersediaan lintas organisasi, ditambah `kpis` dan `counts` kecuali jika `summary=false`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "count": {
                      "type": "integer"
                    },
                    "next": {
                      "type": "integer",
                      "nullable": true,
                      "description": "Offset halaman berikutnya, atau null pada halaman terakhir."
                    },
                    "previous": {
                      "type": "integer",
                      "nullable": true
                    },
                    "results": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NetworkListItem"
                      }
                    },
                    "kpis": {
                      "type": "object",
                      "description": "Setiap kunci adalah {value, delta} atas hasil yang cocok dengan filter saat ini. Dihilangkan saat `summary=false`.",
                      "properties": {
                        "active": {
                          "type": "object"
                        },
                        "in_review": {
                          "type": "object"
                        },
                        "applicants_involved": {
                          "type": "object"
                        },
                        "detected_this_period": {
                          "type": "object"
                        },
                        "false_positive_rate": {
                          "type": "object"
                        }
                      }
                    },
                    "counts": {
                      "$ref": "#/components/schemas/NetworkListCounts"
                    },
                    "sharing_mode": {
                      "type": "string",
                      "enum": [
                        "off",
                        "private",
                        "global"
                      ],
                      "description": "Mode berbagi lintas-organisasi milik organisasi. Hanya `global` yang membandingkan jaringan di seluruh organisasi; `private` dan `off` membatasinya hanya pada riwayat organisasi itu sendiri.",
                      "example": "global"
                    },
                    "cross_org_available": {
                      "type": "boolean",
                      "description": "Menentukan apakah sinyal lintas organisasi berlaku untuk organisasi ini. Fitur ini memerlukan paket Enterprise dan mode berbagi `global`.",
                      "example": true
                    },
                    "cross_org_unavailable_reason": {
                      "type": "string",
                      "enum": [
                        "plan",
                        "sharing_mode"
                      ],
                      "nullable": true,
                      "description": "Alasan mengapa sinyal lintas organisasi tidak berlaku, diperiksa dalam urutan ini. `plan`: paket organisasi tidak mencakup jaringan penipuan lintas organisasi (memerlukan paket Enterprise), apa pun mode berbaginya. `sharing_mode`: paket mencakupnya, tetapi mode berbagi adalah `private` atau `off`. Null jika `cross_org_available` bernilai `true`.",
                      "example": null
                    }
                  },
                  "required": [
                    "count",
                    "next",
                    "previous",
                    "results",
                    "sharing_mode",
                    "cross_org_available",
                    "cross_org_unavailable_reason"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Nilai filter, pengurutan, penomoran halaman, atau `summary` tidak valid.",
            "content": {
              "application/json": {
                "examples": {
                  "Invalid summary": {
                    "summary": "Ringkasan tidak valid",
                    "value": {
                      "summary": [
                        "Must be \"true\" or \"false\"."
                      ]
                    }
                  },
                  "Invalid scope": {
                    "summary": "Cakupan tidak valid",
                    "value": {
                      "scope": [
                        "Use identity or transactions."
                      ]
                    }
                  },
                  "Unsupported ordering": {
                    "summary": "Pengurutan tidak didukung",
                    "value": [
                      "Unsupported ordering."
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Kredensial tidak ada atau tidak valid.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string",
                      "description": "Hadir pada error berkode, misalnya `networks_not_entitled`."
                    }
                  }
                },
                "examples": {
                  "Missing or invalid credentials": {
                    "summary": "Kredensial tidak ada atau tidak valid",
                    "value": {
                      "detail": "Authentication credentials were not provided or are invalid."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Kunci API milik aplikasi lain, atau merupakan kunci dengan akses terbatas: Endpoint Networks memerlukan kunci akses penuh. Token anggota konsol memerlukan `list:networks`. Juga dikembalikan dengan `code: networks_not_entitled` saat Networks tidak diaktifkan untuk organisasi.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string",
                      "description": "Hadir pada error berkode, misalnya `networks_not_entitled`."
                    }
                  }
                },
                "examples": {
                  "Networks not enabled": {
                    "summary": "Jaringan tidak diaktifkan",
                    "value": {
                      "detail": "Networks is disabled for this organization. Contact Didit support if you believe this is an error.",
                      "code": "networks_not_entitled"
                    }
                  },
                  "Restricted API key": {
                    "summary": "Kunci API terbatas",
                    "value": {
                      "detail": "This API key has no access to this endpoint."
                    }
                  },
                  "No permission": {
                    "summary": "Tidak ada izin",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/networks/{network_uuid}/": {
      "get": {
        "summary": "Dapatkan jaringan",
        "description": "Ambil detail lengkap satu jaringan: statistik, tag penipuan, dan sinyal risiko, ditambah `sharing_mode` organisasi dan ketersediaan lintas organisasi, `tags` aplikasi Anda pada jaringan, `outcomes` anggota, serta skor pola (`patterns`). Memerlukan kunci API akses penuh, atau `read:networks` untuk anggota konsol.",
        "operationId": "get_network",
        "x-didit-sdk": {
          "resource": "networks",
          "method": "retrieve",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Networks"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID organisasi."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID aplikasi."
          },
          {
            "name": "network_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "n3a5e000-0000-4000-8000-000000000001"
            },
            "description": "UUID jaringan."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/networks/n3a5e000-0000-4000-8000-000000000001/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.networks.retrieve(\n    \"n3a5e000-0000-4000-8000-000000000001\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.networks.retrieve(\"n3a5e000-0000-4000-8000-000000000001\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Networks.Retrieve(ctx, \"n3a5e000-0000-4000-8000-000000000001\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.networks().retrieve(\"n3a5e000-0000-4000-8000-000000000001\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->networks->retrieve('n3a5e000-0000-4000-8000-000000000001');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.networks.retrieve(\"n3a5e000-0000-4000-8000-000000000001\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Networks.RetrieveAsync(\"n3a5e000-0000-4000-8000-000000000001\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "Detail jaringan.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NetworkDetailResponse"
                },
                "example": {
                  "uuid": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                  "network_id": "N-0042",
                  "name": null,
                  "status": "in_review",
                  "risk": {
                    "score": 82,
                    "band": "high",
                    "bar": 0.82
                  },
                  "pattern_types": [
                    "exact_same_device",
                    "same_email"
                  ],
                  "signal_types": [
                    "device",
                    "email"
                  ],
                  "member_counts": {
                    "total": 3,
                    "users": 3,
                    "businesses": 0,
                    "transaction_parties": 0
                  },
                  "member_status": {
                    "approved": 1,
                    "declined": 1,
                    "in_review": 0,
                    "not_completed": 1
                  },
                  "signal_coverage": {
                    "device": {
                      "signals": 1,
                      "subjects": 3,
                      "coverage": 1.0
                    },
                    "email": {
                      "signals": 1,
                      "subjects": 2,
                      "coverage": 0.6667
                    }
                  },
                  "first_activity_at": "2026-10-01T09:12:44Z",
                  "last_activity_at": "2026-10-12T16:03:10Z",
                  "stats": {
                    "members": {
                      "total": 3,
                      "users": 3,
                      "businesses": 0,
                      "transaction_parties": 0
                    },
                    "member_status": {
                      "approved": 1,
                      "declined": 1,
                      "in_review": 0,
                      "not_completed": 1
                    },
                    "signals": {
                      "total": 2,
                      "by_type": {
                        "device": {
                          "signals": 1,
                          "subjects": 3,
                          "coverage": 1.0
                        },
                        "email": {
                          "signals": 1,
                          "subjects": 2,
                          "coverage": 0.6667
                        }
                      }
                    }
                  },
                  "fraud_tags": [],
                  "risk_signals": {
                    "residential_proxy_reuse": {
                      "detected": false,
                      "signal_count": 0,
                      "max_subject_count": 0
                    },
                    "email_intelligence": {
                      "enriched_signal_count": 1,
                      "high_risk_count": 0,
                      "social_profile_count": 0
                    },
                    "phone_intelligence": {
                      "enriched_signal_count": 0,
                      "high_risk_count": 0
                    }
                  },
                  "reviewed_at": "2026-10-12T16:30:00Z",
                  "reviewed_by": "reviewer@example.com",
                  "review_reason": "Shared device across three new accounts.",
                  "notes_count": 0,
                  "sharing_mode": "global",
                  "cross_org_available": true,
                  "cross_org_unavailable_reason": null,
                  "tags": [
                    {
                      "uuid": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
                      "name": "SUSPICIOUS",
                      "color": "#6366F1",
                      "source": "custom",
                      "added_by": null,
                      "added_at": "2026-10-13T08:15:00Z"
                    }
                  ],
                  "outcomes": {
                    "approved": 1,
                    "declined": 1,
                    "in_review": 0,
                    "total": 3
                  },
                  "patterns": [
                    {
                      "type": "background",
                      "score": 0.8125,
                      "members": 3,
                      "reason": null,
                      "computed_at": "2026-10-13T08:00:00Z"
                    }
                  ]
                }
              }
            }
          },
          "404": {
            "description": "Jaringan tidak ditemukan (atau tidak terlihat oleh aplikasi ini).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Kredensial tidak ada atau tidak valid.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string",
                      "description": "Hadir pada error berkode, misalnya `networks_not_entitled`."
                    }
                  }
                },
                "examples": {
                  "Missing or invalid credentials": {
                    "summary": "Kredensial tidak ada atau tidak valid",
                    "value": {
                      "detail": "Authentication credentials were not provided or are invalid."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Kunci API milik aplikasi lain, atau merupakan kunci dengan akses terbatas: Endpoint Networks memerlukan kunci akses penuh. Token anggota konsol memerlukan `read:networks`. Juga dikembalikan dengan `code: networks_not_entitled` saat Networks tidak diaktifkan untuk organisasi.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string",
                      "description": "Hadir pada error berkode, misalnya `networks_not_entitled`."
                    }
                  }
                },
                "examples": {
                  "Networks not enabled": {
                    "summary": "Jaringan tidak diaktifkan",
                    "value": {
                      "detail": "Networks is disabled for this organization. Contact Didit support if you believe this is an error.",
                      "code": "networks_not_entitled"
                    }
                  },
                  "Restricted API key": {
                    "summary": "Kunci API terbatas",
                    "value": {
                      "detail": "This API key has no access to this endpoint."
                    }
                  },
                  "No permission": {
                    "summary": "Tidak ada izin",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/networks/{network_uuid}/graph/": {
      "get": {
        "summary": "Dapatkan graf jaringan",
        "description": "Ambil jaringan sebagai graf dari node subjek (pengguna vendor, bisnis vendor, pihak transaksi) dan node sinyal (nilai perangkat/IP/wajah/dokumen/telepon/email/alamat bersama yang menghubungkan mereka), dengan sisi yang merepresentasikan keanggotaan.",
        "operationId": "get_network_graph",
        "x-didit-sdk": {
          "resource": "networks",
          "method": "retrieve_graph",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Networks"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID organisasi."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID aplikasi."
          },
          {
            "name": "network_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "n3a5e000-0000-4000-8000-000000000001"
            },
            "description": "UUID jaringan."
          },
          {
            "name": "depth",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "1",
                "2",
                "3",
                "all"
              ]
            },
            "description": "Hop dari subjek fokus yang akan disertakan. Default-nya semua (tidak terbatas)."
          },
          {
            "name": "focus_kind",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "vendor_user",
                "vendor_business",
                "transaction_party"
              ]
            },
            "description": "Tipe subjek untuk memusatkan graf. Wajib diberikan bersama focus_id; default ke anggota arbitrer jika kedalaman dibatasi dan keduanya tidak disediakan."
          },
          {
            "name": "focus_id",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID subjek untuk memusatkan graf."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/networks/n3a5e000-0000-4000-8000-000000000001/graph/?depth=2' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.networks.retrieve_graph(\n    \"n3a5e000-0000-4000-8000-000000000001\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.networks.retrieveGraph(\"n3a5e000-0000-4000-8000-000000000001\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Networks.RetrieveGraph(ctx, \"n3a5e000-0000-4000-8000-000000000001\", didit.NetworksRetrieveGraphParams{})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.networks().retrieveGraph(\"n3a5e000-0000-4000-8000-000000000001\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->networks->retrieveGraph('n3a5e000-0000-4000-8000-000000000001');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.networks.retrieve_graph(\"n3a5e000-0000-4000-8000-000000000001\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Networks.RetrieveGraphAsync(\"n3a5e000-0000-4000-8000-000000000001\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "Graf jaringan.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NetworkGraph"
                }
              }
            }
          },
          "404": {
            "description": "Jaringan tidak ditemukan (atau tidak terlihat oleh aplikasi ini).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/networks/{network_uuid}/members/": {
      "get": {
        "summary": "Mencantumkan anggota jaringan",
        "description": "Daftar subjek (pengguna vendor, bisnis vendor, atau pihak transaksi) yang termasuk dalam jaringan ini.",
        "operationId": "list_network_members",
        "x-didit-sdk": {
          "resource": "networks",
          "method": "list_members",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Networks"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID organisasi."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID aplikasi."
          },
          {
            "name": "network_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "n3a5e000-0000-4000-8000-000000000001"
            },
            "description": "UUID jaringan."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/networks/n3a5e000-0000-4000-8000-000000000001/members/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.networks.list_members(\n    \"n3a5e000-0000-4000-8000-000000000001\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.networks.listMembers(\"n3a5e000-0000-4000-8000-000000000001\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Networks.ListMembers(ctx, \"n3a5e000-0000-4000-8000-000000000001\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.networks().listMembers(\"n3a5e000-0000-4000-8000-000000000001\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->networks->listMembers('n3a5e000-0000-4000-8000-000000000001');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.networks.list_members(\"n3a5e000-0000-4000-8000-000000000001\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Networks.ListMembersAsync(\"n3a5e000-0000-4000-8000-000000000001\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "Anggota jaringan. Tanpa penomoran halaman.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "results": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NetworkMember"
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Jaringan tidak ditemukan (atau tidak terlihat oleh aplikasi ini).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/networks/{network_uuid}/signals/": {
      "get": {
        "summary": "Mencantumkan sinyal jaringan",
        "description": "Daftar sinyal (perangkat bersama, IP, wajah, nomor dokumen, telepon, email, atau nilai alamat) yang menautkan anggota jaringan ini.",
        "operationId": "list_network_signals",
        "x-didit-sdk": {
          "resource": "networks",
          "method": "list_signals",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Networks"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID organisasi."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID aplikasi."
          },
          {
            "name": "network_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "n3a5e000-0000-4000-8000-000000000001"
            },
            "description": "UUID jaringan."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/networks/n3a5e000-0000-4000-8000-000000000001/signals/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.networks.list_signals(\n    \"n3a5e000-0000-4000-8000-000000000001\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.networks.listSignals(\"n3a5e000-0000-4000-8000-000000000001\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Networks.ListSignals(ctx, \"n3a5e000-0000-4000-8000-000000000001\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.networks().listSignals(\"n3a5e000-0000-4000-8000-000000000001\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->networks->listSignals('n3a5e000-0000-4000-8000-000000000001');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.networks.list_signals(\"n3a5e000-0000-4000-8000-000000000001\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Networks.ListSignalsAsync(\"n3a5e000-0000-4000-8000-000000000001\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "Sinyal jaringan. Tanpa penomoran halaman.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "results": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NetworkSignal"
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Jaringan tidak ditemukan (atau tidak terlihat oleh aplikasi ini).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/networks/{network_uuid}/timeline/": {
      "get": {
        "summary": "Dapatkan lini masa jaringan",
        "description": "Tanpa `contract`: event milik jaringan itu sendiri (deteksi, observasi terbaru setiap sinyal beserta peninjauannya), terlama lebih dulu dan tanpa paginasi. `limit`, `cursor`, dan `event_type` diabaikan. Dengan `contract=2`: lini masa bertipe, terbaru lebih dulu dan dipaginasi berdasarkan kursor. Opsi ini menambahkan aktivitas akun anggota (upaya verifikasi, transaksi, proses masuk yang Anda kirimkan melalui API event dan aturan live yang dikenai) serta kasus yang dibuka untuk jaringan tersebut. Event `note_added` hanya dikembalikan kepada anggota konsol, tidak pernah ke kunci API. Memerlukan kunci API akses penuh, atau `read:networks` untuk anggota konsol.",
        "operationId": "get_network_timeline",
        "x-didit-sdk": {
          "resource": "networks",
          "method": "retrieve_timeline",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Networks"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID organisasi."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID aplikasi."
          },
          {
            "name": "network_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "n3a5e000-0000-4000-8000-000000000001"
            },
            "description": "UUID jaringan."
          },
          {
            "name": "contract",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "2"
              ]
            },
            "description": "`2` mengembalikan linimasa bertipe. Jangan sertakan nilai ini untuk linimasa default. Nilai lainnya mengembalikan 400."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 500,
              "default": 100
            },
            "description": "Khusus linimasa bertipe. Event per halaman, 1 hingga 500. Default ke 100."
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Khusus linimasa bertipe. Nilai `next_cursor` dari halaman sebelumnya. Kursor yang tidak valid atau kosong mengembalikan 400."
          },
          {
            "name": "event_type",
            "in": "query",
            "required": false,
            "style": "form",
            "explode": true,
            "schema": {
              "type": "array",
              "maxItems": 20,
              "items": {
                "type": "string",
                "enum": [
                  "network_detected",
                  "signal_observed",
                  "network_active",
                  "network_in_review",
                  "network_resolved",
                  "network_dismissed",
                  "verification_attempt",
                  "transaction",
                  "login",
                  "rule_hit",
                  "case_linked",
                  "note_added"
                ]
              }
            },
            "description": "Khusus linimasa bertipe. Jenis event yang akan disimpan, diulang atau dipisahkan koma, maksimal 20 nilai. Default ke semua jenis."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/networks/n3a5e000-0000-4000-8000-000000000001/timeline/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "curl",
            "label": "curl (typed timeline)",
            "source": "curl -X GET 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/networks/3fa85f64-5717-4562-b3fc-2c963f66afa6/timeline/?contract=2&limit=50&event_type=verification_attempt,login' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.networks.retrieve_timeline(\n    \"n3a5e000-0000-4000-8000-000000000001\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.networks.retrieveTimeline(\"n3a5e000-0000-4000-8000-000000000001\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Networks.RetrieveTimeline(ctx, \"n3a5e000-0000-4000-8000-000000000001\", didit.NetworksRetrieveTimelineParams{})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.networks().retrieveTimeline(\"n3a5e000-0000-4000-8000-000000000001\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->networks->retrieveTimeline('n3a5e000-0000-4000-8000-000000000001');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.networks.retrieve_timeline(\"n3a5e000-0000-4000-8000-000000000001\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Networks.RetrieveTimelineAsync(\"n3a5e000-0000-4000-8000-000000000001\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "Tanpa `contract`: `{results}`, yang terlama lebih dulu, tidak dipaginasi. Dengan `contract=2`: `{results, next_cursor}`, yang terbaru lebih dulu.",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/NetworkTimeline"
                    },
                    {
                      "$ref": "#/components/schemas/NetworkTimelinePage"
                    }
                  ]
                },
                "examples": {
                  "Default timeline": {
                    "summary": "Tanpa contract",
                    "value": {
                      "results": [
                        {
                          "event_type": "network_detected",
                          "occurred_at": "2026-10-01T09:12:44Z",
                          "label": "Network detected",
                          "metadata": {
                            "network_id": "N-0042"
                          }
                        },
                        {
                          "event_type": "signal_observed",
                          "occurred_at": "2026-10-12T16:03:10Z",
                          "label": "device observed",
                          "metadata": {
                            "signal_type": "device",
                            "subject_count": 3,
                            "is_hub": false
                          }
                        },
                        {
                          "event_type": "network_in_review",
                          "occurred_at": "2026-10-12T16:30:00Z",
                          "label": "Network in_review",
                          "metadata": {
                            "reason": "Shared device across three new accounts."
                          }
                        }
                      ]
                    }
                  },
                  "Typed timeline": {
                    "summary": "Dengan contract=2",
                    "value": {
                      "results": [
                        {
                          "id": "monitoring_event:9b2f1c3e-4d5a-4b6c-8d7e-0f1a2b3c4d5e",
                          "event_type": "login",
                          "occurred_at": "2026-10-12T18:41:02Z",
                          "ingested_at": "2026-10-12T18:41:03Z",
                          "label": "Login",
                          "metadata": {},
                          "account": {
                            "node_id": "vendor_user:5f6e7d8c-9b0a-4c1d-8e2f-3a4b5c6d7e8f",
                            "node_type": "account",
                            "uuid": "5f6e7d8c-9b0a-4c1d-8e2f-3a4b5c6d7e8f",
                            "vendor_data": "user-1042",
                            "display_name": "Alex Example",
                            "ownership": "owned",
                            "route": {
                              "kind": "user",
                              "id": "5f6e7d8c-9b0a-4c1d-8e2f-3a4b5c6d7e8f",
                              "application_id": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee"
                            }
                          },
                          "source_ref": {
                            "kind": "monitoring_event",
                            "id": "9b2f1c3e-4d5a-4b6c-8d7e-0f1a2b3c4d5e",
                            "ownership": "owned"
                          },
                          "verification_attempt": null,
                          "transaction": null,
                          "login": {
                            "action": "auth.login",
                            "succeeded": true,
                            "status": "APPROVED",
                            "ip": {
                              "address": "203.0.113.24",
                              "country_code": "ES",
                              "city": "Madrid",
                              "connection_type": null,
                              "is_vpn_or_tor": false,
                              "is_data_center": false
                            },
                            "device": {
                              "fingerprint": "fp_0a1b2c3d",
                              "label": "Chrome · Android"
                            },
                            "is_first_login": false,
                            "is_new_device": true
                          },
                          "rule_hit": null,
                          "case_linked": null,
                          "note_added": null
                        },
                        {
                          "id": "session:1c2d3e4f-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
                          "event_type": "verification_attempt",
                          "occurred_at": "2026-10-12T16:03:10Z",
                          "ingested_at": "2026-10-12T16:03:10Z",
                          "label": "Verification attempt 2 of 2",
                          "metadata": {},
                          "account": {
                            "node_id": "vendor_user:5f6e7d8c-9b0a-4c1d-8e2f-3a4b5c6d7e8f",
                            "node_type": "account",
                            "uuid": "5f6e7d8c-9b0a-4c1d-8e2f-3a4b5c6d7e8f",
                            "vendor_data": "user-1042",
                            "display_name": "Alex Example",
                            "ownership": "owned",
                            "route": {
                              "kind": "user",
                              "id": "5f6e7d8c-9b0a-4c1d-8e2f-3a4b5c6d7e8f",
                              "application_id": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee"
                            }
                          },
                          "source_ref": {
                            "kind": "session",
                            "id": "1c2d3e4f-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
                            "ownership": "owned",
                            "route": {
                              "kind": "session",
                              "id": "1c2d3e4f-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
                              "application_id": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee"
                            }
                          },
                          "verification_attempt": {
                            "session_id": "1c2d3e4f-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
                            "session_number": 1287,
                            "attempt": 2,
                            "attempt_count": 2,
                            "status": "Approved",
                            "status_changed_at": "2026-10-12T16:05:41Z",
                            "decline_reasons": []
                          },
                          "transaction": null,
                          "login": null,
                          "rule_hit": null,
                          "case_linked": null,
                          "note_added": null
                        },
                        {
                          "id": "signal_observed:8d7c6b5a-4e3f-4a2b-9c1d-0e9f8a7b6c5d",
                          "event_type": "signal_observed",
                          "occurred_at": "2026-10-12T16:03:10Z",
                          "ingested_at": "2026-10-01T09:12:44Z",
                          "label": "device observed",
                          "metadata": {
                            "signal_type": "device",
                            "subject_count": 3,
                            "is_hub": false
                          },
                          "account": null,
                          "source_ref": null,
                          "verification_attempt": null,
                          "transaction": null,
                          "login": null,
                          "rule_hit": null,
                          "case_linked": null,
                          "note_added": null
                        }
                      ],
                      "next_cursor": "eyJ0IjoiMjAyNi0xMC0xMlQxNjowMzoxMCswMDowMCIsImMiOiIyMDI2LTEwLTAxVDA5OjEyOjQ0KzAwOjAwIiwiciI6MSwidSI6IjhkN2M2YjVhLTRlM2YtNGEyYi05YzFkLTBlOWY4YTdiNmM1ZCJ9"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Jika `contract` ada: nilai `contract`, `limit`, `cursor`, atau `event_type` tidak valid.",
            "content": {
              "application/json": {
                "examples": {
                  "Unsupported contract": {
                    "summary": "Kontrak tidak didukung",
                    "value": {
                      "contract": [
                        "\"3\" is not a valid choice."
                      ]
                    }
                  },
                  "Invalid cursor": {
                    "summary": "Kursor tidak valid",
                    "value": {
                      "cursor": [
                        "This cursor is not valid. Reload the feed."
                      ]
                    }
                  },
                  "Limit too large": {
                    "summary": "Batas terlalu besar",
                    "value": {
                      "limit": [
                        "Ensure this value is less than or equal to 500."
                      ]
                    }
                  },
                  "Unknown event type": {
                    "summary": "Tipe event tidak dikenal",
                    "value": {
                      "event_type": {
                        "0": [
                          "\"logout\" is not a valid choice."
                        ]
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Kredensial tidak ada atau tidak valid.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string",
                      "description": "Hadir pada error berkode, misalnya `networks_not_entitled`."
                    }
                  }
                },
                "examples": {
                  "Missing or invalid credentials": {
                    "summary": "Kredensial tidak ada atau tidak valid",
                    "value": {
                      "detail": "Authentication credentials were not provided or are invalid."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Kunci API milik aplikasi lain, atau merupakan kunci dengan akses terbatas: Endpoint Networks memerlukan kunci akses penuh. Token anggota konsol memerlukan `read:networks`. Juga dikembalikan dengan `code: networks_not_entitled` saat Networks tidak diaktifkan untuk organisasi.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string",
                      "description": "Hadir pada error berkode, misalnya `networks_not_entitled`."
                    }
                  }
                },
                "examples": {
                  "Networks not enabled": {
                    "summary": "Jaringan tidak diaktifkan",
                    "value": {
                      "detail": "Networks is disabled for this organization. Contact Didit support if you believe this is an error.",
                      "code": "networks_not_entitled"
                    }
                  },
                  "Restricted API key": {
                    "summary": "Kunci API terbatas",
                    "value": {
                      "detail": "This API key has no access to this endpoint."
                    }
                  },
                  "No permission": {
                    "summary": "Tidak ada izin",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Jaringan tidak ditemukan (atau tidak terlihat oleh aplikasi ini).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/networks/{network_uuid}/map/": {
      "get": {
        "summary": "Dapatkan peta jaringan",
        "description": "Titik geografis tempat alamat/lokasi anggota jaringan ini bertemu, bersumber dari sesi, sesi bisnis, dan transaksi yang mendukung keanggotaannya.",
        "operationId": "get_network_map",
        "x-didit-sdk": {
          "resource": "networks",
          "method": "retrieve_map",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Networks"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID organisasi."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID aplikasi."
          },
          {
            "name": "network_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "n3a5e000-0000-4000-8000-000000000001"
            },
            "description": "UUID jaringan."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/networks/n3a5e000-0000-4000-8000-000000000001/map/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.networks.retrieve_map(\n    \"n3a5e000-0000-4000-8000-000000000001\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.networks.retrieveMap(\"n3a5e000-0000-4000-8000-000000000001\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Networks.RetrieveMap(ctx, \"n3a5e000-0000-4000-8000-000000000001\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.networks().retrieveMap(\"n3a5e000-0000-4000-8000-000000000001\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->networks->retrieveMap('n3a5e000-0000-4000-8000-000000000001');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.networks.retrieve_map(\"n3a5e000-0000-4000-8000-000000000001\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Networks.RetrieveMapAsync(\"n3a5e000-0000-4000-8000-000000000001\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "Peta jaringan.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NetworkMap"
                }
              }
            }
          },
          "404": {
            "description": "Jaringan tidak ditemukan (atau tidak terlihat oleh aplikasi ini).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/sessions/{session_id}/networks/": {
      "get": {
        "summary": "Mencantumkan jaringan untuk sesi",
        "description": "Mencantumkan daftar jaringan tempat pengguna vendor dari sesi tergabung. Diselesaikan melalui pengguna yang ditautkan dengan vendor_data sesi.",
        "operationId": "list_session_network_memberships",
        "x-didit-sdk": {
          "resource": "sessions",
          "method": "list_networks",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Networks"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID organisasi."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID aplikasi."
          },
          {
            "name": "session_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID sesi."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/sessions/aaaaaaaa-0000-4000-8000-000000000001/networks/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.sessions.list_networks(\n    \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.sessions.listNetworks(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.ListNetworks(ctx, \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.sessions().listNetworks(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->sessions->listNetworks('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.sessions.list_networks(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.ListNetworksAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "Jaringan tempat entitas ini menjadi anggota. Tanpa penomoran halaman.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EntityNetworkMembershipList"
                }
              }
            }
          },
          "404": {
            "description": "Entitas tidak ditemukan dalam aplikasi ini, atau tidak memiliki subjek tertaut untuk dicari.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/business-sessions/{business_session_id}/networks/": {
      "get": {
        "summary": "Mencantumkan jaringan untuk sesi bisnis",
        "description": "Mencantumkan daftar jaringan tempat bisnis vendor dari sesi bisnis tergabung.",
        "operationId": "list_business_session_network_memberships",
        "x-didit-sdk": {
          "resource": "business_sessions",
          "method": "list_networks",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Networks"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID organisasi."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID aplikasi."
          },
          {
            "name": "business_session_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID sesi bisnis."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/business-sessions/aaaaaaaa-0000-4000-8000-000000000002/networks/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.business_sessions.list_networks(\n    \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.businessSessions.listNetworks(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.BusinessSessions.ListNetworks(ctx, \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.businessSessions().listNetworks(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->businessSessions->listNetworks('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.business_sessions.list_networks(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.BusinessSessions.ListNetworksAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "Jaringan tempat entitas ini menjadi anggota. Tanpa penomoran halaman.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EntityNetworkMembershipList"
                }
              }
            }
          },
          "404": {
            "description": "Entitas tidak ditemukan dalam aplikasi ini, atau tidak memiliki subjek tertaut untuk dicari.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/users/{vendor_user_uuid}/networks/": {
      "get": {
        "summary": "Mencantumkan jaringan untuk pengguna",
        "description": "Mencantumkan daftar jaringan tempat pengguna vendor tergabung.",
        "operationId": "list_user_network_memberships",
        "x-didit-sdk": {
          "resource": "users",
          "method": "list_networks",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Networks"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID organisasi."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID aplikasi."
          },
          {
            "name": "vendor_user_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID pengguna vendor."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/users/aaaaaaaa-0000-4000-8000-000000000003/networks/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.users.list_networks(\n    \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.users.listNetworks(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Users.ListNetworks(ctx, \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.users().listNetworks(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->users->listNetworks('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.users.list_networks(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Users.ListNetworksAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "Jaringan tempat entitas ini menjadi anggota. Tanpa penomoran halaman.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EntityNetworkMembershipList"
                }
              }
            }
          },
          "404": {
            "description": "Entitas tidak ditemukan dalam aplikasi ini, atau tidak memiliki subjek tertaut untuk dicari.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/businesses/{vendor_business_uuid}/networks/": {
      "get": {
        "summary": "Mencantumkan jaringan untuk bisnis",
        "description": "Mencantumkan daftar jaringan tempat bisnis vendor tergabung.",
        "operationId": "list_business_network_memberships",
        "x-didit-sdk": {
          "resource": "businesses",
          "method": "list_networks",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Networks"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID organisasi."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID aplikasi."
          },
          {
            "name": "vendor_business_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID bisnis vendor."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/businesses/aaaaaaaa-0000-4000-8000-000000000004/networks/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.businesses.list_networks(\n    \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.businesses.listNetworks(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Businesses.ListNetworks(ctx, \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.businesses().listNetworks(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->businesses->listNetworks('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.businesses.list_networks(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Businesses.ListNetworksAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "Jaringan tempat entitas ini menjadi anggota. Tanpa penomoran halaman.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EntityNetworkMembershipList"
                }
              }
            }
          },
          "404": {
            "description": "Entitas tidak ditemukan dalam aplikasi ini, atau tidak memiliki subjek tertaut untuk dicari.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/transactions/{transaction_uuid}/networks/": {
      "get": {
        "summary": "Mencantumkan jaringan untuk transaksi",
        "description": "Mencantumkan daftar jaringan tempat subjek KYC/KYB pendukung transaksi tergabung (diselesaikan melalui sesi atau sesi bisnis transaksi).",
        "operationId": "list_transaction_network_memberships",
        "x-didit-sdk": {
          "resource": "transactions",
          "method": "list_networks",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Networks"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID organisasi."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID aplikasi."
          },
          {
            "name": "transaction_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID transaksi."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/transactions/aaaaaaaa-0000-4000-8000-000000000005/networks/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.transactions.list_networks(\n    \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.transactions.listNetworks(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Transactions.ListNetworks(ctx, \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.transactions().listNetworks(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->transactions->listNetworks('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.transactions.list_networks(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Transactions.ListNetworksAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "Jaringan tempat entitas ini menjadi anggota. Tanpa penomoran halaman.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EntityNetworkMembershipList"
                }
              }
            }
          },
          "404": {
            "description": "Entitas tidak ditemukan dalam aplikasi ini, atau tidak memiliki subjek tertaut untuk dicari.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/transactions/{transaction_uuid}/parties/{transaction_party_uuid}/networks/": {
      "get": {
        "summary": "Mencantumkan jaringan untuk pihak transaksi",
        "description": "Mencantumkan daftar jaringan tempat pihak transaksi (pengirim, penerima, atau pihak lawan) tergabung, yang diselesaikan melalui pihak itu sendiri dan bukan melalui sesi pendukung transaksi.",
        "operationId": "list_transaction_party_network_memberships",
        "x-didit-sdk": {
          "resource": "transactions",
          "method": "list_party_networks",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Networks"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID organisasi."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID aplikasi."
          },
          {
            "name": "transaction_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID transaksi."
          },
          {
            "name": "transaction_party_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID pihak transaksi."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/transactions/aaaaaaaa-0000-4000-8000-000000000005/parties/bbbbbbbb-0000-4000-8000-000000000006/networks/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.transactions.list_party_networks(\n    \"11111111-2222-3333-4444-555555555555\",\n    \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.transactions.listPartyNetworks(\n  \"11111111-2222-3333-4444-555555555555\",\n  \"11111111-2222-3333-4444-555555555555\",\n);\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Transactions.ListPartyNetworks(ctx, \"11111111-2222-3333-4444-555555555555\", \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.transactions().listPartyNetworks(\"11111111-2222-3333-4444-555555555555\", \"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->transactions->listPartyNetworks('11111111-2222-3333-4444-555555555555', '11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.transactions.list_party_networks(\n  \"11111111-2222-3333-4444-555555555555\",\n  \"11111111-2222-3333-4444-555555555555\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Transactions.ListPartyNetworksAsync(\"11111111-2222-3333-4444-555555555555\", \"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "Jaringan tempat entitas ini menjadi anggota. Tanpa penomoran halaman.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EntityNetworkMembershipList"
                }
              }
            }
          },
          "404": {
            "description": "Entitas tidak ditemukan dalam aplikasi ini, atau tidak memiliki subjek tertaut untuk dicari.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/biometric-templates/": {
      "get": {
        "summary": "Mencantumkan templat biometrik yang disimpan",
        "description": "Aplikasi yang ikut serta menyimpan satu templat biometrik wajah tanpa gambar yang dikelola secara terpisah dan ditautkan ke Pengguna ketika sesi dihapus (lihat `DELETE /v3/session/{sessionId}/delete/`). Templat adalah data biometrik dengan `expires_at` yang terbatas; templat tidak pernah berisi gambar, data sesi, atau kolom identitas, dan dihapus secara permanen saat Pengguna dihapus, penghapusan privasi, kedaluwarsa, atau penghapusan permanen eksplisit. Endpoint ini hanya menerima kunci API aplikasi (`x-api-key`); token pengguna Business Console akan ditolak dengan `403`.\n\nMengembalikan daftar terpaginasi dari templat yang saat ini disimpan oleh aplikasi. Templat yang telah dihapus permanen tidak dicantumkan.",
        "operationId": "list_biometric_templates",
        "x-didit-sdk": {
          "resource": "biometric_templates",
          "method": "list",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Biometric Templates"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "in": "query",
            "name": "vendor_data",
            "required": false,
            "description": "Pencocokan substring yang tidak peka huruf besar/kecil pada `vendor_data` milik Pengguna yang memilikinya saat ini.",
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "vendor_user_uuid",
            "required": false,
            "description": "Kecocokan persis pada pengguna pemilik.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "in": "query",
            "name": "status",
            "required": false,
            "description": "Status siklus hidup. Templat yang dihapus permanen tidak akan pernah dicantumkan.",
            "schema": {
              "type": "string",
              "enum": [
                "pending",
                "active",
                "expired",
                "held_out_of_use",
                "purge_pending",
                "purge_failed"
              ]
            }
          },
          {
            "in": "query",
            "name": "source_type",
            "required": false,
            "description": "Bagaimana templat dibuat.",
            "schema": {
              "type": "string",
              "enum": [
                "session_delete",
                "automatic_retention",
                "backfill"
              ]
            }
          },
          {
            "in": "query",
            "name": "retained_from",
            "required": false,
            "description": "Templat yang dipertahankan pada atau setelah waktu ini.",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "in": "query",
            "name": "retained_to",
            "required": false,
            "description": "Templat yang dipertahankan pada atau sebelum waktu ini. Tidak boleh lebih awal dari `retained_from` (`400`).",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "in": "query",
            "name": "ordering",
            "required": false,
            "description": "Urutan pengurutan.",
            "schema": {
              "type": "string",
              "enum": [
                "retained_at",
                "-retained_at",
                "expires_at",
                "-expires_at"
              ],
              "default": "-retained_at"
            }
          },
          {
            "in": "query",
            "name": "limit",
            "required": false,
            "description": "Ukuran halaman.",
            "schema": {
              "type": "integer"
            }
          },
          {
            "in": "query",
            "name": "offset",
            "required": false,
            "description": "Offset paginasi.",
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Templat terpaginasi.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "count": {
                      "type": "integer"
                    },
                    "next": {
                      "type": "string",
                      "nullable": true
                    },
                    "previous": {
                      "type": "string",
                      "nullable": true
                    },
                    "results": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "uuid": {
                            "type": "string",
                            "format": "uuid",
                            "description": "ID templat. Dibuat secara acak; tidak diturunkan dari sesi yang dihapus atau wajahnya."
                          },
                          "vendor_user_uuid": {
                            "type": "string",
                            "format": "uuid",
                            "description": "Pengguna pemilik."
                          },
                          "vendor_data": {
                            "type": "string",
                            "nullable": true,
                            "description": "`vendor_data` Pengguna saat ini, diselesaikan saat Anda membaca templat (tidak pernah disalin)."
                          },
                          "source_type": {
                            "type": "string",
                            "enum": [
                              "session_delete",
                              "automatic_retention",
                              "backfill"
                            ],
                            "description": "Cara templat dibuat: penghapusan sesi (API atau Console), jendela retensi data otomatis aplikasi, atau backfill yang dilakukan Didit atas instruksi Anda."
                          },
                          "provenance_reference": {
                            "type": "string",
                            "format": "uuid",
                            "description": "Referensi tidak transparan yang menghubungkan templat ke jejak auditnya. Ini bukan id sesi yang dihapus dan tidak dapat dikaitkan dengan id tersebut."
                          },
                          "retention_policy": {
                            "type": "string",
                            "enum": [
                              "delete_with_session",
                              "retain_until_user_deleted"
                            ],
                            "description": "Kebijakan aplikasi pada saat retensi."
                          },
                          "retention_override": {
                            "type": "boolean",
                            "nullable": true,
                            "description": "Nilai `retain_face_embeddings` yang dikirim pada penghapusan, atau `null` saat kebijakan diterapkan."
                          },
                          "retained_at": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "expires_at": {
                            "type": "string",
                            "format": "date-time",
                            "description": "Waktu templat kedaluwarsa dan dihapus secara otomatis. Selalu ditetapkan."
                          },
                          "retained_by": {
                            "type": "string",
                            "nullable": true,
                            "description": "Prinsipal yang memberikan instruksi: id aplikasi untuk kunci API, id anggota Console untuk tindakan Console, atau pengidentifikasi `service:` untuk retensi otomatis. Tidak pernah berupa alamat email."
                          },
                          "retained_by_type": {
                            "type": "string",
                            "enum": [
                              "API_KEY",
                              "CONSOLE_USER",
                              "SYSTEM"
                            ]
                          },
                          "instruction_class": {
                            "type": "string",
                            "enum": [
                              "operational_session_delete",
                              "privacy_erasure"
                            ]
                          },
                          "instruction_source": {
                            "type": "string",
                            "enum": [
                              "api",
                              "console",
                              "automatic_retention",
                              "backfill",
                              "privacy_erasure",
                              "explicit_template_purge",
                              "vendor_user_delete",
                              "expiry",
                              "reconciliation",
                              "migration",
                              "system"
                            ]
                          },
                          "instruction_id": {
                            "type": "string",
                            "description": "`instruction_id` yang dikirim pada penghapusan, atau id yang dibuat oleh Didit."
                          },
                          "held_out_of_use": {
                            "type": "boolean",
                            "description": "`true` hanya selama penahanan hukum berlaku. Templat yang ditahan dikecualikan dari semua pencocokan."
                          },
                          "status": {
                            "type": "string",
                            "enum": [
                              "pending",
                              "active",
                              "expired",
                              "held_out_of_use",
                              "purge_pending",
                              "purge_failed",
                              "purged"
                            ],
                            "description": "Hanya templat `active` yang tidak ditahan, belum melewati `expires_at`, dan Penggunanya masih ada yang diikutsertakan dalam pencocokan."
                          },
                          "purged_at": {
                            "type": "string",
                            "format": "date-time",
                            "nullable": true
                          }
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "One active template": {
                    "value": {
                      "count": 1,
                      "next": null,
                      "previous": null,
                      "results": [
                        {
                          "uuid": "9d2f4b6e-1c3a-4e8f-b7d5-0a1c2e3f4a5b",
                          "vendor_user_uuid": "2f7c1a9e-8b4d-4c6a-9e1f-3d5b7a9c1e2f",
                          "vendor_data": "user-42",
                          "source_type": "session_delete",
                          "provenance_reference": "6b1e8d2f-4a3c-4f9e-8c7d-1a2b3c4d5e6f",
                          "retention_policy": "retain_until_user_deleted",
                          "retention_override": null,
                          "retained_at": "2026-08-28T10:15:42.318402Z",
                          "expires_at": "2027-08-28T10:15:42.318402Z",
                          "retained_by": "3c9e2b1f-7d4a-4e8b-9c1d-5f6a7b8c9d0e",
                          "retained_by_type": "API_KEY",
                          "instruction_class": "operational_session_delete",
                          "instruction_source": "api",
                          "instruction_id": "post-approval-cleanup-2026-08",
                          "held_out_of_use": false,
                          "status": "active",
                          "purged_at": null
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Nilai filter tidak valid, atau `retained_to` lebih awal dari `retained_from`. Kesalahan validasi dengan kunci berdasarkan kolom.",
            "content": {
              "application/json": {
                "examples": {
                  "Bad range": {
                    "value": {
                      "retained_to": [
                        "Must be on or after retained_from."
                      ]
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Token pengguna konsol, atau kunci API tidak diizinkan. Endpoint ini hanya menerima kunci API aplikasi.",
            "content": {
              "application/json": {
                "examples": {
                  "Forbidden": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/biometric-templates/?vendor_data=user-42&status=active' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nfor item in client.biometric_templates.list():\n    print(item)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nfor await (const item of didit.biometricTemplates.list()) {\n  console.log(item);\n}"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\niter := client.BiometricTemplates.ListAutoPaging(ctx, didit.BiometricTemplatesListParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nfor (var item : client.biometricTemplates().list()) {\n    System.out.println(item);\n}"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\nforeach ($didit->biometricTemplates->list() as $item) {\n    print_r($item->toArray());\n}"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.biometric_templates.list.auto_paging_each do |item|\n  puts item.to_h\nend"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.BiometricTemplates.ListAsync())\n{\n    Console.WriteLine(JsonSerializer.Serialize(item));\n}"
          }
        ]
      }
    },
    "/v3/biometric-templates/count/": {
      "get": {
        "summary": "Hitung templat biometrik yang disimpan",
        "description": "Aplikasi yang ikut serta menyimpan satu templat biometrik wajah tanpa gambar yang dikelola secara terpisah dan ditautkan ke Pengguna ketika sesi dihapus (lihat `DELETE /v3/session/{sessionId}/delete/`). Templat adalah data biometrik dengan `expires_at` yang terbatas; templat tidak pernah berisi gambar, data sesi, atau kolom identitas, dan akan dihapus secara permanen saat Pengguna dihapus, penghapusan privasi, kedaluwarsa, atau penghapusan permanen eksplisit. Endpoint ini hanya menerima kunci API aplikasi (`x-api-key`); token pengguna Business Console akan ditolak dengan `403`.\n\nMengembalikan jumlah templat yang cocok dengan filter yang sama seperti endpoint daftar. Gunakan ini untuk memeriksa apa saja yang akan terpengaruh oleh penghapusan permanen massal berfilter dengan `delete_all: true`.",
        "operationId": "count_biometric_templates",
        "x-didit-sdk": {
          "resource": "biometric_templates",
          "method": "count",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Biometric Templates"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "in": "query",
            "name": "vendor_data",
            "required": false,
            "description": "Pencocokan substring yang tidak peka huruf besar/kecil pada `vendor_data` milik Pengguna yang memilikinya saat ini.",
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "vendor_user_uuid",
            "required": false,
            "description": "Kecocokan persis pada pengguna pemilik.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "in": "query",
            "name": "status",
            "required": false,
            "description": "Status siklus hidup. Templat yang dihapus permanen tidak akan pernah dicantumkan.",
            "schema": {
              "type": "string",
              "enum": [
                "pending",
                "active",
                "expired",
                "held_out_of_use",
                "purge_pending",
                "purge_failed"
              ]
            }
          },
          {
            "in": "query",
            "name": "source_type",
            "required": false,
            "description": "Bagaimana templat dibuat.",
            "schema": {
              "type": "string",
              "enum": [
                "session_delete",
                "automatic_retention",
                "backfill"
              ]
            }
          },
          {
            "in": "query",
            "name": "retained_from",
            "required": false,
            "description": "Templat yang dipertahankan pada atau setelah waktu ini.",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "in": "query",
            "name": "retained_to",
            "required": false,
            "description": "Templat yang dipertahankan pada atau sebelum waktu ini. Tidak boleh lebih awal dari `retained_from` (`400`).",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Jumlah.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "count": {
                      "type": "integer",
                      "minimum": 0
                    }
                  }
                },
                "examples": {
                  "Count": {
                    "value": {
                      "count": 128
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Nilai filter tidak valid, atau `retained_to` lebih awal dari `retained_from`. Kesalahan validasi dengan kunci berdasarkan kolom.",
            "content": {
              "application/json": {
                "examples": {
                  "Bad range": {
                    "value": {
                      "retained_to": [
                        "Must be on or after retained_from."
                      ]
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Token pengguna konsol, atau kunci API tidak diizinkan. Endpoint ini hanya menerima kunci API aplikasi.",
            "content": {
              "application/json": {
                "examples": {
                  "Forbidden": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/biometric-templates/count/?status=active' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.biometric_templates.count()\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.biometricTemplates.count();\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.BiometricTemplates.Count(ctx, didit.BiometricTemplatesCountParams{})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.biometricTemplates().count();\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->biometricTemplates->count();\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.biometric_templates.count\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.BiometricTemplates.CountAsync();\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/biometric-templates/{template_uuid}/": {
      "get": {
        "summary": "Dapatkan templat biometrik yang disimpan",
        "description": "Aplikasi yang ikut serta menyimpan satu templat biometrik wajah tanpa gambar yang dikelola secara terpisah dan ditautkan ke Pengguna ketika sesi dihapus (lihat `DELETE /v3/session/{sessionId}/delete/`). Templat adalah data biometrik dengan `expires_at` yang terbatas; templat tidak pernah berisi gambar, data sesi, atau kolom identitas, dan akan dihapus secara permanen saat Pengguna dihapus, penghapusan privasi, kedaluwarsa, atau penghapusan permanen eksplisit. Endpoint ini hanya menerima kunci API aplikasi (`x-api-key`); token pengguna Business Console akan ditolak dengan `403`.\n\nMengembalikan satu templat. Respons tidak pernah menyertakan gambar, vektor, id sesi yang dihapus, atau data identitas.",
        "operationId": "get_biometric_template",
        "x-didit-sdk": {
          "resource": "biometric_templates",
          "method": "retrieve",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Biometric Templates"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "in": "path",
            "name": "template_uuid",
            "required": true,
            "description": "ID templat, seperti yang dikembalikan dalam `biometric_template_uuid` oleh endpoint penghapusan sesi, `biometric_template_id` pada kecocokan Pencarian Wajah, atau endpoint daftar.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "9d2f4b6e-1c3a-4e8f-b7d5-0a1c2e3f4a5b"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Templat.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "uuid": {
                      "type": "string",
                      "format": "uuid",
                      "description": "ID templat. Dibuat secara acak; tidak diturunkan dari sesi yang dihapus atau wajahnya."
                    },
                    "vendor_user_uuid": {
                      "type": "string",
                      "format": "uuid",
                      "description": "Pengguna pemilik."
                    },
                    "vendor_data": {
                      "type": "string",
                      "nullable": true,
                      "description": "`vendor_data` Pengguna saat ini, diselesaikan saat Anda membaca templat (tidak pernah disalin)."
                    },
                    "source_type": {
                      "type": "string",
                      "enum": [
                        "session_delete",
                        "automatic_retention",
                        "backfill"
                      ],
                      "description": "Cara templat dibuat: penghapusan sesi (API atau Console), jendela retensi data otomatis aplikasi, atau backfill yang dilakukan Didit atas instruksi Anda."
                    },
                    "provenance_reference": {
                      "type": "string",
                      "format": "uuid",
                      "description": "Referensi tidak transparan yang menghubungkan templat ke jejak auditnya. Ini bukan id sesi yang dihapus dan tidak dapat dikaitkan dengan id tersebut."
                    },
                    "retention_policy": {
                      "type": "string",
                      "enum": [
                        "delete_with_session",
                        "retain_until_user_deleted"
                      ],
                      "description": "Kebijakan aplikasi pada saat retensi."
                    },
                    "retention_override": {
                      "type": "boolean",
                      "nullable": true,
                      "description": "Nilai `retain_face_embeddings` yang dikirim pada penghapusan, atau `null` saat kebijakan diterapkan."
                    },
                    "retained_at": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "expires_at": {
                      "type": "string",
                      "format": "date-time",
                      "description": "Waktu templat kedaluwarsa dan dihapus secara otomatis. Selalu ditetapkan."
                    },
                    "retained_by": {
                      "type": "string",
                      "nullable": true,
                      "description": "Prinsipal yang memberikan instruksi: id aplikasi untuk kunci API, id anggota Console untuk tindakan Console, atau pengidentifikasi `service:` untuk retensi otomatis. Tidak pernah berupa alamat email."
                    },
                    "retained_by_type": {
                      "type": "string",
                      "enum": [
                        "API_KEY",
                        "CONSOLE_USER",
                        "SYSTEM"
                      ]
                    },
                    "instruction_class": {
                      "type": "string",
                      "enum": [
                        "operational_session_delete",
                        "privacy_erasure"
                      ]
                    },
                    "instruction_source": {
                      "type": "string",
                      "enum": [
                        "api",
                        "console",
                        "automatic_retention",
                        "backfill",
                        "privacy_erasure",
                        "explicit_template_purge",
                        "vendor_user_delete",
                        "expiry",
                        "reconciliation",
                        "migration",
                        "system"
                      ]
                    },
                    "instruction_id": {
                      "type": "string",
                      "description": "`instruction_id` yang dikirim pada penghapusan, atau id yang dibuat oleh Didit."
                    },
                    "held_out_of_use": {
                      "type": "boolean",
                      "description": "`true` hanya selama penahanan hukum berlaku. Templat yang ditahan dikecualikan dari semua pencocokan."
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "pending",
                        "active",
                        "expired",
                        "held_out_of_use",
                        "purge_pending",
                        "purge_failed",
                        "purged"
                      ],
                      "description": "Hanya templat `active` yang tidak ditahan, belum melewati `expires_at`, dan Penggunanya masih ada yang diikutsertakan dalam pencocokan."
                    },
                    "purged_at": {
                      "type": "string",
                      "format": "date-time",
                      "nullable": true
                    }
                  }
                },
                "examples": {
                  "Active template": {
                    "value": {
                      "uuid": "9d2f4b6e-1c3a-4e8f-b7d5-0a1c2e3f4a5b",
                      "vendor_user_uuid": "2f7c1a9e-8b4d-4c6a-9e1f-3d5b7a9c1e2f",
                      "vendor_data": "user-42",
                      "source_type": "session_delete",
                      "provenance_reference": "6b1e8d2f-4a3c-4f9e-8c7d-1a2b3c4d5e6f",
                      "retention_policy": "retain_until_user_deleted",
                      "retention_override": null,
                      "retained_at": "2026-08-28T10:15:42.318402Z",
                      "expires_at": "2027-08-28T10:15:42.318402Z",
                      "retained_by": "3c9e2b1f-7d4a-4e8b-9c1d-5f6a7b8c9d0e",
                      "retained_by_type": "API_KEY",
                      "instruction_class": "operational_session_delete",
                      "instruction_source": "api",
                      "instruction_id": "post-approval-cleanup-2026-08",
                      "held_out_of_use": false,
                      "status": "active",
                      "purged_at": null
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Token pengguna konsol, atau kunci API tidak diizinkan. Endpoint ini hanya menerima kunci API aplikasi.",
            "content": {
              "application/json": {
                "examples": {
                  "Forbidden": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Templat tidak dikenal, templat dari aplikasi lain, atau (pada `GET`) templat yang telah dihapus secara permanen.",
            "content": {
              "application/json": {
                "examples": {
                  "Not found": {
                    "value": {
                      "detail": "Biometric template not found."
                    }
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET https://verification.didit.me/v3/biometric-templates/9d2f4b6e-1c3a-4e8f-b7d5-0a1c2e3f4a5b/ \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.biometric_templates.retrieve(\n    \"9d2f4b6e-1c3a-4e8f-b7d5-0a1c2e3f4a5b\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.biometricTemplates.retrieve(\"9d2f4b6e-1c3a-4e8f-b7d5-0a1c2e3f4a5b\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.BiometricTemplates.Retrieve(ctx, \"9d2f4b6e-1c3a-4e8f-b7d5-0a1c2e3f4a5b\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.biometricTemplates().retrieve(\"9d2f4b6e-1c3a-4e8f-b7d5-0a1c2e3f4a5b\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->biometricTemplates->retrieve('9d2f4b6e-1c3a-4e8f-b7d5-0a1c2e3f4a5b');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.biometric_templates.retrieve(\"9d2f4b6e-1c3a-4e8f-b7d5-0a1c2e3f4a5b\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.BiometricTemplates.RetrieveAsync(\"9d2f4b6e-1c3a-4e8f-b7d5-0a1c2e3f4a5b\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      },
      "delete": {
        "summary": "Hapus permanen templat biometrik yang disimpan",
        "description": "Aplikasi yang ikut serta menyimpan satu templat biometrik wajah tanpa gambar yang dikelola secara terpisah dan ditautkan ke Pengguna ketika sesi dihapus (lihat `DELETE /v3/session/{sessionId}/delete/`). Templat adalah data biometrik dengan `expires_at` yang memiliki masa berlaku terbatas; templat tidak pernah berisi gambar, data sesi, atau kolom identitas, dan akan dihapus permanen saat Pengguna dihapus, penghapusan privasi, kedaluwarsa, atau penghapusan permanen eksplisit. Endpoint-endpoint ini hanya menerima kunci API aplikasi (`x-api-key`); token pengguna Business Console akan ditolak dengan `403`.\n\nMenghapus permanen satu templat: templat dihapus dari semua jenis pencocokan dan templat yang disimpan akan dihapus. Bersifat tidak dapat dibatalkan dan dicatat pada log audit bersama pihak yang melakukan tindakan.\n\n**Semantik coba lagi:** Didit menghapus templat yang disimpan terlebih dahulu dan baru menandai templat telah dihapus permanen. Jika penyimpanan biometrik tidak tersedia, panggilan mengembalikan `503`, templat beralih ke `status: purge_failed` dan sudah dikecualikan dari pencocokan; ulangi panggilan yang sama untuk menyelesaikan. Mengulangi penghapusan permanen pada templat yang sudah dihapus permanen mengembalikan `already_purged`.\n\nTemplat juga dihapus permanen oleh `POST /v3/users/delete/` untuk Pengguna pemilik, oleh penghapusan apa pun pada sesi Pengguna tersebut dengan `deletion_instruction: privacy_erasure`, dan secara otomatis pada `expires_at`.",
        "operationId": "purge_biometric_template",
        "x-didit-sdk": {
          "resource": "biometric_templates",
          "method": "delete",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Biometric Templates"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "in": "path",
            "name": "template_uuid",
            "required": true,
            "description": "ID templat, seperti yang dikembalikan dalam `biometric_template_uuid` oleh endpoint penghapusan sesi, `biometric_template_id` pada kecocokan Pencarian Wajah, atau endpoint daftar.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "9d2f4b6e-1c3a-4e8f-b7d5-0a1c2e3f4a5b"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Hasil penghapusan permanen.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "uuid": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "outcome": {
                      "type": "string",
                      "enum": [
                        "purged",
                        "already_purged"
                      ]
                    }
                  }
                },
                "examples": {
                  "Purged": {
                    "value": {
                      "uuid": "9d2f4b6e-1c3a-4e8f-b7d5-0a1c2e3f4a5b",
                      "outcome": "purged"
                    }
                  },
                  "Already purged": {
                    "value": {
                      "uuid": "9d2f4b6e-1c3a-4e8f-b7d5-0a1c2e3f4a5b",
                      "outcome": "already_purged"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Token pengguna konsol, atau kunci API tidak diizinkan. Endpoint ini hanya menerima kunci API aplikasi.",
            "content": {
              "application/json": {
                "examples": {
                  "Forbidden": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Templat tidak dikenal, templat dari aplikasi lain, atau (pada `GET`) templat yang telah dihapus secara permanen.",
            "content": {
              "application/json": {
                "examples": {
                  "Not found": {
                    "value": {
                      "detail": "Biometric template not found."
                    }
                  }
                }
              }
            }
          },
          "503": {
            "description": "Penyimpanan biometrik tidak tersedia saat mempertahankan atau menghapus total templat biometrik. Tidak ada yang dihapus; ulangi permintaan yang sama. Coba lagi bersifat idempoten dan mengarah pada satu templat tunggal.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Retryable": {
                    "value": {
                      "detail": "The biometric-template operation could not finish because an external store is unavailable. The operation is retryable."
                    }
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X DELETE https://verification.didit.me/v3/biometric-templates/9d2f4b6e-1c3a-4e8f-b7d5-0a1c2e3f4a5b/ \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.biometric_templates.delete(\n    \"9d2f4b6e-1c3a-4e8f-b7d5-0a1c2e3f4a5b\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.biometricTemplates.delete(\"9d2f4b6e-1c3a-4e8f-b7d5-0a1c2e3f4a5b\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.BiometricTemplates.Delete(ctx, \"9d2f4b6e-1c3a-4e8f-b7d5-0a1c2e3f4a5b\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.biometricTemplates().delete(\"9d2f4b6e-1c3a-4e8f-b7d5-0a1c2e3f4a5b\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->biometricTemplates->delete('9d2f4b6e-1c3a-4e8f-b7d5-0a1c2e3f4a5b');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.biometric_templates.delete(\"9d2f4b6e-1c3a-4e8f-b7d5-0a1c2e3f4a5b\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.BiometricTemplates.DeleteAsync(\"9d2f4b6e-1c3a-4e8f-b7d5-0a1c2e3f4a5b\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/biometric-templates/delete/": {
      "post": {
        "summary": "Pembersihan massal templat biometrik yang disimpan",
        "description": "Aplikasi yang mengaktifkan opsi ini menyimpan satu templat biometrik wajah tanpa gambar yang dikelola secara terpisah dan ditautkan ke Pengguna saat sesi dihapus (lihat `DELETE /v3/session/{sessionId}/delete/`). Templat adalah data biometrik dengan `expires_at` yang terbatas; templat tidak pernah berisi gambar, data sesi, atau kolom identitas, dan templat akan dibersihkan saat penghapusan Pengguna, penghapusan privasi, kedaluwarsa, atau pembersihan eksplisit. Endpoint ini hanya menerima kunci API aplikasi (`x-api-key`); token pengguna Business Console ditolak dengan `403`.\n\nMembersihkan banyak templat dalam satu panggilan, melalui daftar id eksplisit atau dengan `delete_all: true` yang secara opsional dipersempit oleh filter yang sama seperti endpoint daftar. Templat dibersihkan satu per satu dan setiap hasil melaporkan `purged` atau `already_purged`. Jika penyimpanan biometrik tidak tersedia, panggilan mengembalikan `503` pada templat pertama yang gagal: templat yang dibersihkan lebih awal dalam permintaan tetap dibersihkan, templat yang gagal berpindah ke `purge_failed` (sudah dikecualikan dari pencocokan), dan mengulangi permintaan akan menyelesaikan prosesnya.\n\n**`delete_all: true` tanpa filter membersihkan setiap templat biometrik di aplikasi dan tidak dapat dibatalkan.** Jalankan endpoint penghitungan dengan filter yang sama terlebih dahulu.",
        "operationId": "bulk_purge_biometric_templates",
        "x-didit-sdk": {
          "resource": "biometric_templates",
          "method": "batch_delete",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Biometric Templates"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "template_uuids": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "minItems": 1,
                    "description": "Templat yang akan dihapus. Diperlukan kecuali `delete_all` bernilai `true`. ID yang sudah dihapus dilaporkan sebagai `already_purged`."
                  },
                  "delete_all": {
                    "type": "boolean",
                    "default": false,
                    "description": "Jika `true`, menghapus permanen setiap templat yang cocok dengan filter di bawah ini (semua templat aplikasi jika tidak ada filter yang diberikan). `template_uuids` diabaikan. Tidak dapat dibatalkan."
                  },
                  "vendor_data": {
                    "type": "string",
                    "description": "Hanya dengan `delete_all`: pencocokan substring tanpa membedakan huruf besar/kecil pada `vendor_data` Pengguna pemilik."
                  },
                  "vendor_user_uuid": {
                    "type": "string",
                    "format": "uuid",
                    "description": "Hanya dengan `delete_all`: pencocokan persis pada Pengguna pemilik."
                  },
                  "status": {
                    "type": "string",
                    "enum": [
                      "pending",
                      "active",
                      "expired",
                      "held_out_of_use",
                      "purge_pending",
                      "purge_failed"
                    ],
                    "description": "Hanya dengan `delete_all`."
                  },
                  "source_type": {
                    "type": "string",
                    "enum": [
                      "session_delete",
                      "automatic_retention",
                      "backfill"
                    ],
                    "description": "Hanya dengan `delete_all`."
                  },
                  "retained_from": {
                    "type": "string",
                    "format": "date-time",
                    "description": "Hanya dengan `delete_all`."
                  },
                  "retained_to": {
                    "type": "string",
                    "format": "date-time",
                    "description": "Hanya dengan `delete_all`. Tidak boleh lebih awal dari `retained_from`."
                  }
                }
              },
              "examples": {
                "By id": {
                  "value": {
                    "template_uuids": [
                      "9d2f4b6e-1c3a-4e8f-b7d5-0a1c2e3f4a5b",
                      "1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d"
                    ]
                  }
                },
                "Every template of one User": {
                  "value": {
                    "delete_all": true,
                    "vendor_user_uuid": "2f7c1a9e-8b4d-4c6a-9e1f-3d5b7a9c1e2f"
                  }
                },
                "Every template in the application": {
                  "value": {
                    "delete_all": true
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Hasil pembersihan per templat.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "results": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "uuid": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "outcome": {
                            "type": "string",
                            "enum": [
                              "purged",
                              "already_purged"
                            ]
                          }
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "Mixed": {
                    "value": {
                      "results": [
                        {
                          "uuid": "9d2f4b6e-1c3a-4e8f-b7d5-0a1c2e3f4a5b",
                          "outcome": "purged"
                        },
                        {
                          "uuid": "1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
                          "outcome": "already_purged"
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Kesalahan validasi — tidak ada yang dihapus menyeluruh.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing selector": {
                    "value": {
                      "template_uuids": [
                        "This field is required unless delete_all is true."
                      ]
                    }
                  },
                  "Bad range": {
                    "value": {
                      "retained_to": [
                        "Must be on or after retained_from."
                      ]
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Token pengguna konsol, atau kunci API tidak diizinkan. Endpoint ini hanya menerima kunci API aplikasi.",
            "content": {
              "application/json": {
                "examples": {
                  "Forbidden": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "503": {
            "description": "Penyimpanan biometrik tidak tersedia saat mempertahankan atau menghapus total templat biometrik. Tidak ada yang dihapus; ulangi permintaan yang sama. Coba lagi bersifat idempoten dan mengarah pada satu templat tunggal.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Retryable": {
                    "value": {
                      "detail": "The biometric-template operation could not finish because an external store is unavailable. The operation is retryable."
                    }
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST https://verification.didit.me/v3/biometric-templates/delete/ \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"delete_all\": true, \"vendor_user_uuid\": \"2f7c1a9e-8b4d-4c6a-9e1f-3d5b7a9c1e2f\"}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.biometric_templates.batch_delete(\n    template_uuids=[\"9d2f4b6e-1c3a-4e8f-b7d5-0a1c2e3f4a5b\", \"1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d\"],\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.biometricTemplates.batchDelete({\n  template_uuids: [\"9d2f4b6e-1c3a-4e8f-b7d5-0a1c2e3f4a5b\", \"1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d\"],\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.BiometricTemplates.BatchDelete(ctx, didit.BiometricTemplatesBatchDeleteParams{\n\tTemplateUUIDs: didit.Some([]string{\"9d2f4b6e-1c3a-4e8f-b7d5-0a1c2e3f4a5b\", \"1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d\"}),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.List;\nimport me.didit.Didit;\nimport me.didit.types.BiometricTemplatesBatchDeleteParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.biometricTemplates().batchDelete(BiometricTemplatesBatchDeleteParams.builder()\n        .templateUuids(List.of(\"9d2f4b6e-1c3a-4e8f-b7d5-0a1c2e3f4a5b\", \"1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d\"))\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->biometricTemplates->batchDelete([\n    'template_uuids' => ['9d2f4b6e-1c3a-4e8f-b7d5-0a1c2e3f4a5b', '1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d'],\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.biometric_templates.batch_delete(template_uuids: [\"9d2f4b6e-1c3a-4e8f-b7d5-0a1c2e3f4a5b\", \"1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d\"])\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.BiometricTemplates.BatchDeleteAsync(new BiometricTemplatesBatchDeleteParams\n{\n    TemplateUuids = new string[] { \"9d2f4b6e-1c3a-4e8f-b7d5-0a1c2e3f4a5b\", \"1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d\" },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/kyb/shareholders/": {
      "post": {
        "summary": "Perusahaan registri KYB dengan pemegang saham (mandiri)",
        "operationId": "post_v3_kyb_shareholders",
        "x-didit-sdk": {
          "resource": "kyb",
          "method": "list_shareholders",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Standalone APIs"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [],
        "description": "Ambil profil Lite **ditambah pemegang saham langsung** (orang pribadi dan entitas perusahaan, beserta rentang kepemilikan mereka) dari satu kandidat yang dikembalikan oleh `POST /v3/kyb/search/`.\n\n**Penyandingan dengan pencarian.** Teruskan `kyb_response_id` kandidat persis seperti yang dikembalikan oleh pencarian pada aplikasi yang sama. Lakukan pencarian pada tingkat yang ingin Anda beli (`tier` pada `POST /v3/kyb/search/`), karena pencarian berjalan pada rantai registri yang melayani tingkat tersebut dan pencarian Lite yang kosong bukanlah bukti bahwa registri tidak memuat perusahaan tersebut. Ketika data kepemilikan negara tersebut berada di registri lain, Didit akan mencari ulang perusahaan di sana berdasarkan nomor registrasi, tanpa biaya tambahan.\n\n**Penagihan.** Ditagihkan sesuai harga Pemegang Saham negara terkait - lihat [harga registri KYB](/id/getting-started/kyb-registry-pricing). Ketika registri tidak memuat catatan pemegang saham untuk perusahaan tersebut (atau negara tersebut tidak menyediakan data kepemilikan sama sekali), profil Lite yang akan dikirimkan dan ditagihkan sebagai gantinya: baca `registry_tier_delivered` dan `registry_ownership_status`. Saldo diperiksa terhadap harga Pemegang Saham sebelum panggilan registri apa pun (`403` jika kurang).\n\n**Ketersediaan.** Hanya v3. Setiap panggilan membuat sesi bisnis (id-nya adalah `request_id`).\n\n**Laporan yang tertunda.** Ketika laporan masih disiapkan, atau bagian kepemilikan belum diambil dari registri, endpoint mengembalikan 202 Accepted, kyb_registry.fetch_status=pending, kyb_registry.registry_ownership_status=pending, dan registry_tier_delivered=null. Simpan request_id dan panggil GET /v3/session/{request_id}/decision/ hingga registry_checks[0].company.fetch_status terselesaikan. Didit menyelesaikan laporan secara otomatis dan menagihkan tingkat yang terkirim setelah siap. Jangan mengulangi pembelian saat masih tertunda; setiap POST baru membuat permintaan terpisah.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/KYBRegistryCandidateRequest"
              },
              "example": {
                "kyb_response_id": "69aeeb95febb0f1704042259",
                "vendor_data": "company-1234"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST https://verification.didit.me/v3/kyb/shareholders/ \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"kyb_response_id\": \"69aeeb95febb0f1704042259\",\n    \"vendor_data\": \"company-1234\"\n  }'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.kyb.list_shareholders(\n    kyb_response_id=\"69aeeb95febb0f1704042259\",\n    vendor_data=\"company-1234\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.kyb.listShareholders({\n  kyb_response_id: \"69aeeb95febb0f1704042259\",\n  vendor_data: \"company-1234\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.KYB.ListShareholders(ctx, didit.KYBRegistryCandidateRequest{\n\tKYBResponseID: \"69aeeb95febb0f1704042259\",\n\tVendorData:    didit.String(\"company-1234\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.KYBRegistryCandidateRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.kyb().listShareholders(KYBRegistryCandidateRequest.builder()\n        .kybResponseId(\"69aeeb95febb0f1704042259\")\n        .vendorData(\"company-1234\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->kyb->listShareholders([\n    'kyb_response_id' => '69aeeb95febb0f1704042259',\n    'vendor_data' => 'company-1234',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.kyb.list_shareholders(\n  kyb_response_id: \"69aeeb95febb0f1704042259\",\n  vendor_data: \"company-1234\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Kyb.ListShareholdersAsync(new KYBRegistryCandidateRequest\n{\n    KybResponseId = \"69aeeb95febb0f1704042259\",\n    VendorData = \"company-1234\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "Laporan perusahaan dikembalikan dan ditagihkan pada tingkat yang diberikan. Laporan kepemilikan yang masih dipersiapkan dapat mengembalikan 202; simpan request_id untuk mengambil keputusan yang disimpan.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "request_id": {
                      "type": "string",
                      "format": "uuid",
                      "description": "ID sesi bisnis yang dibuat untuk pengambilan ini. Catatan yang disimpan (terlihat di konsol) terus diperbarui jika registri berhasil menyelesaikan pencarian setelah respons."
                    },
                    "registry_tier_requested": {
                      "type": "string",
                      "enum": [
                        "basic",
                        "shareholders",
                        "ubo"
                      ],
                      "description": "Tingkat yang dijual endpoint ini: `basic` (Lite) untuk opsi tertentu, `shareholders`, `ubo`."
                    },
                    "registry_tier_delivered": {
                      "type": "string",
                      "enum": [
                        "basic",
                        "shareholders",
                        "ubo",
                        null
                      ],
                      "description": "Tingkat yang benar-benar dikirimkan dan ditagihkan. Lebih rendah dari yang diminta jika registri negara tersebut tidak menyimpan data kepemilikan, atau registri tidak memiliki catatan kepemilikan untuk perusahaan ini.",
                      "nullable": true
                    },
                    "kyb_registry": {
                      "type": "object",
                      "description": "Profil perusahaan registri lengkap.",
                      "properties": {
                        "uuid": {
                          "type": "string",
                          "format": "uuid",
                          "description": "ID Didit untuk catatan perusahaan ini."
                        },
                        "node_id": {
                          "type": "string",
                          "example": "feature_kyb_registry"
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "Not Finished",
                            "Approved",
                            "Declined",
                            "In Review"
                          ],
                          "description": "Penilaian Didit atas pemeriksaan registri (misalnya `In Review` ketika perusahaan tidak aktif di registri atau data kepemilikan tidak dapat diturunkan)."
                        },
                        "registry_status": {
                          "type": "string",
                          "nullable": true,
                          "enum": [
                            "active",
                            "dissolved",
                            "deregistered",
                            "see full details",
                            "authorised",
                            "appointed representative",
                            "unauthorised",
                            "inactive",
                            "no longer authorised",
                            "closed",
                            "struck off",
                            null
                          ],
                          "description": "Status perusahaan yang dinormalisasi sebagaimana dilaporkan oleh registri."
                        },
                        "data_resolved": {
                          "type": "boolean",
                          "description": "`true` setelah registri mengembalikan profil lengkap. `false` jika registri masih memproses setelah polling — data yang disimpan akan selesai secara otomatis setelah registri selesai memproses."
                        },
                        "company_name": {
                          "type": "string",
                          "example": "Tesco PLC"
                        },
                        "registration_number": {
                          "type": "string",
                          "nullable": true,
                          "example": "00445790"
                        },
                        "country_code": {
                          "type": "string",
                          "description": "ISO 3166-1 alpha-2.",
                          "example": "GB"
                        },
                        "region": {
                          "type": "string",
                          "nullable": true,
                          "description": "Kode subdivisi jika registri bersifat regional (misalnya `CA` untuk `US-CA`); kosong jika tidak."
                        },
                        "company_type": {
                          "type": "string",
                          "nullable": true,
                          "example": "Public Limited Company"
                        },
                        "incorporation_date": {
                          "type": "string",
                          "format": "date",
                          "nullable": true,
                          "example": "1947-11-27"
                        },
                        "registered_address": {
                          "type": "string",
                          "nullable": true,
                          "example": "Tesco House, Shire Park, Kestrel Way, Welwyn Garden City, United Kingdom, AL7 1GA"
                        },
                        "tax_number": {
                          "type": "string",
                          "nullable": true,
                          "example": "GB412 8925 93"
                        },
                        "risk_level": {
                          "type": "string",
                          "nullable": true,
                          "description": "Tingkat risiko yang dilaporkan registri, jika tersedia."
                        },
                        "verification_status": {
                          "type": "string",
                          "enum": [
                            "verified",
                            "failed",
                            "unknown"
                          ],
                          "nullable": true,
                          "description": "Status verifikasi lintas yurisdiksi: `verified` ketika status registri menetapkan status hukum aktif (`active`), `failed` ketika menyatakan bahwa perusahaan tidak lagi berstatus baik (misalnya `dissolved`), jika tidak maka `unknown`. Bernilai `null` untuk perusahaan yang tidak berasal dari registri dan selama pemilihan masih `pending`."
                        },
                        "is_from_registry": {
                          "type": "boolean",
                          "description": "Selalu `true` untuk endpoint ini — profil diambil dari registri resmi."
                        },
                        "fetch_status": {
                          "type": "string",
                          "enum": [
                            "pending",
                            "resolved"
                          ],
                          "description": "Siklus hidup pengambilan registri. Dicerminkan oleh `data_resolved`."
                        },
                        "alternative_names": {
                          "type": "string",
                          "nullable": true,
                          "description": "Nama perusahaan alternatif, nama dagang, nama terdahulu, atau nama dalam bahasa asli sebagai teks, jika dilaporkan."
                        },
                        "nature_of_business": {
                          "type": "string",
                          "nullable": true,
                          "description": "Deskripsi aktivitas atau kode klasifikasi, jika dilaporkan."
                        },
                        "registered_capital": {
                          "type": "string",
                          "nullable": true
                        },
                        "registered_capital_amount": {
                          "type": "string",
                          "nullable": true,
                          "description": "Jumlah desimal sebagai string, saat dilaporkan."
                        },
                        "registered_capital_currency": {
                          "type": "string",
                          "nullable": true,
                          "description": "Kode ISO 4217, saat dilaporkan."
                        },
                        "website": {
                          "type": "string",
                          "nullable": true,
                          "example": "https://www.tesco.com/"
                        },
                        "email": {
                          "type": "string",
                          "nullable": true,
                          "example": "customer.service@tesco.co.uk"
                        },
                        "phone": {
                          "type": "string",
                          "nullable": true,
                          "example": "03301231688"
                        },
                        "legal_entity_identifier": {
                          "type": "string",
                          "nullable": true,
                          "description": "LEI, jika dilaporkan."
                        },
                        "location_of_registration": {
                          "type": "string",
                          "nullable": true,
                          "description": "Registri/yurisdiksi tempat perusahaan terdaftar, jika dilaporkan."
                        },
                        "vat_number": {
                          "type": "string",
                          "nullable": true,
                          "description": "Nomor PPN Uni Eropa, saat dikumpulkan selama langkah registri yang di-hosting atau diedit sesudahnya. Saat dipilih, nilai ini biasanya belum ditetapkan — validasi PPN dan ID pajak dijalankan ketika pengguna akhir mengirimkan langkah registri dalam alur yang di-hosting."
                        },
                        "vat_validation_status": {
                          "type": "string",
                          "enum": [
                            "valid",
                            "invalid",
                            "format_valid",
                            "invalid_format",
                            "could_not_validate",
                            "not_applicable"
                          ],
                          "description": "Hasil validasi nomor PPN atau, jika tidak ada, `tax_number`, saat pengiriman ke registri. `valid` / `invalid`: ditentukan oleh registri resmi negara (EU VIES, Norwegia, Swiss, Brasil, Kolombia, Kosta Rika, Ekuador, Paraguay; Polandia juga melalui registri PPN domestiknya). `format_valid` / `invalid_format`: ditentukan oleh aturan format dan digit centang negara tersebut jika tidak ada registri yang dapat dikueri. `could_not_validate`: registri tidak tersedia. `not_applicable`: tidak ada nomor, negara tanpa registri atau aturan, atau sesi sandbox."
                        },
                        "vat_validated_number": {
                          "type": "string",
                          "nullable": true,
                          "description": "Nomor yang diperiksa, sebagaimana diketahui oleh sumber (misalnya nomor PPN yang diperoleh dari SIREN Prancis atau RSIN Belanda). `null` jika tidak ada pemeriksaan yang dijalankan."
                        },
                        "vat_validation_source": {
                          "type": "string",
                          "nullable": true,
                          "enum": [
                            "eu_vies",
                            "pl_vat_white_list",
                            "no_brreg",
                            "ch_uid_register",
                            "br_receita_federal",
                            "co_rues",
                            "cr_hacienda",
                            "ec_sri",
                            "py_dnit",
                            "format_rules",
                            null
                          ],
                          "description": "Sumber yang menentukan `vat_validation_status`: registri resmi, atau `format_rules`. `null` jika tidak ada pemeriksaan yang dijalankan."
                        },
                        "vat_validated_name": {
                          "type": "string",
                          "nullable": true,
                          "description": "Nama yang terdaftar pada sumber yang memvalidasi nomor tersebut, jika menyediakannya. Hanya ditetapkan saat statusnya `valid`."
                        },
                        "vat_validated_address": {
                          "type": "string",
                          "nullable": true,
                          "description": "Alamat yang terdaftar pada sumber yang memvalidasi nomor tersebut, jika sumber mengungkapkannya. Hanya diisi jika statusnya `valid`."
                        },
                        "vat_checked_at": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true,
                          "description": "Cap waktu pemeriksaan. `null` jika tidak ada pemeriksaan yang dilakukan."
                        },
                        "financial_summary": {
                          "type": "object",
                          "nullable": true,
                          "description": "Detail saham/modal yang dilaporkan registri (mata uang, total saham, kelas saham), jika tersedia."
                        },
                        "officers": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "uuid": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "name": {
                                "type": "string",
                                "example": "MELISSA BETHELL"
                              },
                              "designation": {
                                "type": "string",
                                "nullable": true,
                                "description": "Penetapan registri mentah (misalnya `Director`, `Secretary`)."
                              },
                              "role": {
                                "type": "string",
                                "description": "Peran yang dinormalisasi yang diturunkan dari sebutan. Kumpulan model 17 nilai lengkap; penguraian registri pada endpoint ini biasanya menghasilkan director, non_executive_director, secretary, chairman, atau company_officer.",
                                "enum": [
                                  "director",
                                  "non_executive_director",
                                  "secretary",
                                  "chairman",
                                  "ubo",
                                  "shareholder",
                                  "representative",
                                  "founder",
                                  "legal_advisor",
                                  "authorized_signatory",
                                  "trustee",
                                  "beneficiary",
                                  "company_officer",
                                  "settlor",
                                  "protector",
                                  "investor",
                                  "other"
                                ]
                              },
                              "nationality": {
                                "type": "string",
                                "nullable": true
                              },
                              "is_active": {
                                "type": "boolean",
                                "description": "`false` saat registri menandai pengangkatan telah berakhir karena pengunduran diri."
                              },
                              "kyc_status": {
                                "type": "string",
                                "nullable": true,
                                "enum": [
                                  "Approved",
                                  "Declined",
                                  "Pending",
                                  null
                                ],
                                "description": "Status sesi KYC terkait, jika ada yang dimulai untuk pejabat ini. Jika tidak, bernilai `null`."
                              },
                              "kyc_session_url": {
                                "type": "string",
                                "nullable": true,
                                "description": "URL verifikasi dari sesi KYC terkait, jika ada."
                              },
                              "first_name": {
                                "type": "string",
                                "nullable": true,
                                "description": "Nama depan ketika dilaporkan secara eksplisit oleh registri; tidak disimpulkan dari nama lengkap."
                              },
                              "last_name": {
                                "type": "string",
                                "nullable": true,
                                "description": "Nama keluarga ketika dilaporkan secara eksplisit oleh registri."
                              },
                              "address": {
                                "type": "string",
                                "nullable": true,
                                "description": "Alamat pejabat yang dilaporkan oleh registri."
                              },
                              "appointment_date": {
                                "type": "string",
                                "nullable": true,
                                "description": "Tanggal petugas diangkat.",
                                "format": "date"
                              },
                              "termination_date": {
                                "type": "string",
                                "nullable": true,
                                "description": "Tanggal pengangkatan berakhir, jika dilaporkan.",
                                "format": "date"
                              },
                              "date_of_birth": {
                                "type": "string",
                                "nullable": true,
                                "description": "Tanggal lahir lengkap yang dilaporkan registri. Bernilai null jika hanya tahun atau bulan lahir yang diketahui.",
                                "format": "date"
                              },
                              "date_of_birth_year": {
                                "type": "integer",
                                "nullable": true,
                                "minimum": 1,
                                "maximum": 9999,
                                "description": "Tahun lahir yang dilaporkan registri, termasuk saat tanggal lengkap tidak tersedia."
                              },
                              "date_of_birth_month": {
                                "type": "integer",
                                "nullable": true,
                                "minimum": 1,
                                "maximum": 12,
                                "description": "Bulan lahir yang dilaporkan registri. Null jika hanya tahun yang diketahui."
                              }
                            }
                          },
                          "description": "Direktur, sekretaris, dan petugas lainnya yang diekstrak dari registri."
                        },
                        "beneficial_owners": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "uuid": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "name": {
                                "type": "string"
                              },
                              "first_name": {
                                "type": "string",
                                "nullable": true
                              },
                              "last_name": {
                                "type": "string",
                                "nullable": true
                              },
                              "entity_type": {
                                "type": "string",
                                "enum": [
                                  "person",
                                  "company"
                                ],
                                "description": "Apakah pemiliknya adalah perorangan atau entitas korporat."
                              },
                              "roles": {
                                "type": "array",
                                "items": {
                                  "type": "string"
                                },
                                "description": "Peran yang dinormalisasi (misalnya `ubo`, `shareholder`)."
                              },
                              "ownership_min_shares": {
                                "type": "string",
                                "nullable": true,
                                "description": "Batas bawah rentang kepemilikan yang dilaporkan oleh registri (misalnya `25%`)."
                              },
                              "ownership_max_shares": {
                                "type": "string",
                                "nullable": true,
                                "description": "Batas atas rentang kepemilikan yang dilaporkan oleh registri."
                              },
                              "is_active": {
                                "type": "boolean"
                              },
                              "kyc_status": {
                                "type": "string",
                                "nullable": true,
                                "enum": [
                                  "Approved",
                                  "Declined",
                                  "Pending",
                                  null
                                ]
                              },
                              "kyc_session_url": {
                                "type": "string",
                                "nullable": true
                              },
                              "effective_ownership_percent": {
                                "type": "number",
                                "nullable": true,
                                "description": "Persentase kepemilikan terurai (batas maksimum, beralih ke batas minimum jika tidak ada)."
                              },
                              "company_name": {
                                "type": "string",
                                "nullable": true
                              },
                              "registration_number": {
                                "type": "string",
                                "nullable": true
                              },
                              "country_of_birth": {
                                "type": "string",
                                "nullable": true
                              },
                              "email": {
                                "type": "string",
                                "nullable": true
                              },
                              "nationality": {
                                "type": "string",
                                "nullable": true
                              },
                              "designation": {
                                "type": "string",
                                "nullable": true
                              },
                              "voting_min_shares": {
                                "type": "string",
                                "nullable": true
                              },
                              "voting_max_shares": {
                                "type": "string",
                                "nullable": true
                              },
                              "date_of_birth": {
                                "type": "string",
                                "nullable": true,
                                "description": "Tanggal lahir lengkap jika dilaporkan.",
                                "format": "date"
                              },
                              "appointment_date": {
                                "type": "string",
                                "nullable": true,
                                "description": "Tanggal penunjukan saat dilaporkan.",
                                "format": "date"
                              },
                              "shareholding": {
                                "$ref": "#/components/schemas/KYBRegistryShareholding"
                              }
                            }
                          },
                          "description": "Pemilik manfaat / pihak dengan kendali signifikan yang diekstrak dari registri. Dapat bernilai kosong jika registri tidak mencantumkan kepemilikan."
                        },
                        "addresses": {
                          "type": "array",
                          "nullable": true,
                          "description": "Setiap alamat yang dinyatakan oleh registri, satu bentuk kanonikal. Null jika tidak ada yang dinyatakan.",
                          "items": {
                            "$ref": "#/components/schemas/KYBRegistryAddress"
                          }
                        },
                        "industries": {
                          "type": "array",
                          "nullable": true,
                          "description": "Aktivitas yang diklasifikasikan oleh registri untuk perusahaan, dalam satu format kanonis. Bernilai null jika tidak ada yang dinyatakan.",
                          "items": {
                            "$ref": "#/components/schemas/KYBRegistryIndustry"
                          }
                        },
                        "accounts": {
                          "type": "object",
                          "nullable": true,
                          "additionalProperties": true,
                          "description": "Tanggal pengajuan registri, jika tersedia. Laporan tahunan dan rapat umum menggunakan last_annual_return_date dan last_agm_date; keduanya berbeda dari laporan keuangan."
                        },
                        "registry_data": {
                          "$ref": "#/components/schemas/KYBRegistryData"
                        },
                        "user_provided_data": {
                          "type": "object",
                          "nullable": true,
                          "description": "Selalu `null` pada endpoint ini (digunakan oleh alur KYB yang di-hosting saat pengguna akhir mengedit data registri)."
                        },
                        "confirmed_by_user_at": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true,
                          "description": "Selalu `null` pada endpoint ini."
                        },
                        "last_console_edit_at": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true,
                          "description": "Ditetapkan saat peninjau konsol mengedit catatan tersebut nanti."
                        },
                        "is_editable": {
                          "type": "boolean",
                          "description": "Apakah data yang bersumber dari registri masih dapat diedit di alur yang di-hosting atau di konsol."
                        },
                        "registry_tier_delivered": {
                          "type": "string",
                          "enum": [
                            "basic",
                            "shareholders",
                            "ubo",
                            null
                          ],
                          "description": "Sama dengan `registry_tier_delivered` di tingkat teratas.",
                          "nullable": true
                        },
                        "registry_ownership_status": {
                          "type": "string",
                          "nullable": true,
                          "enum": [
                            "not_requested",
                            "delivered",
                            "not_held",
                            "unavailable",
                            "pending",
                            null
                          ],
                          "description": "`delivered` saat data kepemilikan berhasil diperoleh, `not_held` saat registri kepemilikan merespons dan tidak mencantumkan perusahaan ini (lihat `registry_data.ownership_error`), `unavailable` saat tingkat kepemilikan diminta tetapi registri tidak memilikinya untuk perusahaan ini atau tidak dapat dimintai keterangan (lihat `registry_data.ownership_error`), `pending` saat bagian kepemilikan belum diambil dari registri dan Didit masih menyelesaikannya, `not_requested` pada tingkat Lite."
                        },
                        "ownership": {
                          "$ref": "#/components/schemas/KYBRegistryOwnership"
                        },
                        "registry_tier": {
                          "type": "string",
                          "nullable": true,
                          "description": "Tingkat registri yang dipesan oleh alur kerja: `basic`, `shareholders`, atau `ubo`. Juga terdapat di `ownership.tier_requested`."
                        },
                        "registry_monitoring": {
                          "type": "object",
                          "nullable": true,
                          "description": "Pemantau registri terbaru untuk perusahaan, atau `null` jika tidak ada.",
                          "properties": {
                            "uuid": {
                              "type": "string",
                              "format": "uuid"
                            },
                            "status": {
                              "type": "string"
                            },
                            "unavailable_reason": {
                              "type": "string",
                              "nullable": true
                            },
                            "enrolled_at": {
                              "type": "string",
                              "format": "date-time",
                              "nullable": true
                            },
                            "cancelled_at": {
                              "type": "string",
                              "format": "date-time",
                              "nullable": true
                            },
                            "last_bill_date": {
                              "type": "string",
                              "format": "date",
                              "nullable": true
                            },
                            "next_bill_date": {
                              "type": "string",
                              "format": "date",
                              "nullable": true
                            },
                            "last_event_at": {
                              "type": "string",
                              "format": "date-time",
                              "nullable": true
                            },
                            "events_count": {
                              "type": "integer"
                            },
                            "watched_fields": {
                              "description": "Kolom perusahaan yang dipantau oleh pemantau."
                            }
                          }
                        }
                      }
                    },
                    "vendor_data": {
                      "type": "string",
                      "nullable": true,
                      "description": "Menampilkan kembali `vendor_data` yang Anda kirimkan."
                    },
                    "metadata": {
                      "type": "object",
                      "nullable": true,
                      "description": "Salinan `metadata` yang Anda kirimkan."
                    },
                    "created_at": {
                      "type": "string",
                      "format": "date-time"
                    }
                  }
                },
                "examples": {
                  "Resolved company": {
                    "summary": "Profil registri lengkap (daftar pejabat dipersingkat untuk menghemat tempat)",
                    "value": {
                      "request_id": "9d4f2c7a-1b3e-4a5c-8d6f-0e9a8b7c6d5e",
                      "kyb_registry": {
                        "uuid": "f1e2d3c4-b5a6-4789-9c0d-1e2f3a4b5c6d",
                        "node_id": "feature_kyb_registry",
                        "status": "In Review",
                        "registry_status": "active",
                        "data_resolved": true,
                        "company_name": "Tesco PLC",
                        "registration_number": "00445790",
                        "country_code": "GB",
                        "region": "",
                        "company_type": "Public Limited Company",
                        "incorporation_date": "1947-11-27",
                        "registered_address": "Tesco House, Shire Park, Kestrel Way, Welwyn Garden City, United Kingdom, AL7 1GA",
                        "tax_number": "GB412 8925 93",
                        "risk_level": "low risk",
                        "verification_status": "verified",
                        "is_from_registry": true,
                        "fetch_status": "resolved",
                        "alternative_names": "TESCO STORES (HOLDINGS) PUBLIC LIMITED COMPANY",
                        "nature_of_business": null,
                        "registered_capital": null,
                        "registered_capital_amount": null,
                        "registered_capital_currency": null,
                        "website": "https://www.tesco.com/",
                        "email": "customer.service@tesco.co.uk",
                        "phone": "03301231688",
                        "legal_entity_identifier": null,
                        "location_of_registration": null,
                        "financial_summary": {
                          "currency": "Pound (£)",
                          "total_number_of_shares": "8174378721",
                          "meta_detail": {
                            "Class_Of_Share": "Ordinary"
                          }
                        },
                        "officers": [
                          {
                            "uuid": "a1b2c3d4-e5f6-4789-9a0b-1c2d3e4f5a6b",
                            "name": "CHRISTOPHER JON TAYLOR",
                            "designation": "Secretary",
                            "role": "secretary",
                            "nationality": null,
                            "is_active": true,
                            "kyc_status": null,
                            "kyc_session_url": null
                          },
                          {
                            "uuid": "b2c3d4e5-f6a7-4890-8b1c-2d3e4f5a6b7c",
                            "name": "MELISSA BETHELL",
                            "designation": "Director",
                            "role": "director",
                            "nationality": "British",
                            "is_active": true,
                            "kyc_status": null,
                            "kyc_session_url": null
                          }
                        ],
                        "beneficial_owners": [],
                        "addresses": [
                          {
                            "address": "Tesco House, Shire Park, Kestrel Way, Welwyn Garden City, United Kingdom, AL7 1GA",
                            "type": "legal_entity_registry_address",
                            "description": "registered office address"
                          }
                        ],
                        "industries": null,
                        "accounts": {
                          "last_account": "26 February 2025",
                          "next_account": "26 February 2026",
                          "due_by_date": "26 August 2026"
                        },
                        "registry_data": {},
                        "user_provided_data": null,
                        "confirmed_by_user_at": null,
                        "last_console_edit_at": null,
                        "is_editable": true
                      },
                      "vendor_data": "company-1234",
                      "metadata": null,
                      "created_at": "2026-06-11T10:45:00.000000+00:00"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Kesalahan validasi. Masalah tingkat kolom menggunakan format standar DRF.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing kyb_response_id": {
                    "summary": "`kyb_response_id` diperlukan",
                    "value": {
                      "kyb_response_id": [
                        "This field is required."
                      ]
                    }
                  },
                  "save_api_request=false rejected": {
                    "summary": "Pilihan selalu disimpan",
                    "value": {
                      "save_api_request": [
                        "KYB registry select must be saved so billing and retrieval can be tracked."
                      ]
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Izin ditolak. Dikembalikan ketika header `x-api-key` tidak ada, dan juga ketika saldo organisasi pemanggil tidak dapat mencukupi biaya panggilan tersebut; kunci yang salah, dicabut, atau kedaluwarsa mengembalikan `401`. Kunci yang tidak ada mengembalikan `403` dengan `{\"detail\": ...}`; kunci yang salah, dicabut, atau kedaluwarsa mengembalikan `401`. Kekurangan kredit mengembalikan `403` dengan `{\"error\": ...}` sebelum skrining atau panggilan penyedia apa pun terjadi.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing or invalid API key": {
                    "summary": "Tidak ada header `x-api-key`, atau kuncinya tidak valid/dicabut",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Not enough credits": {
                    "summary": "Saldo organisasi tidak mencukupi untuk panggilan ini",
                    "value": {
                      "error": "You don't have enough credits to perform this request. Please top up at https://business.didit.me"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Batas laju terlampaui. Endpoint POST/PATCH/DELETE berbagi anggaran 300 permintaan penulisan per menit per kunci API (pembuatan transaksi dan ingesti event memiliki anggaran terpisah sebesar 600). Respons menyertakan header `X-RateLimit-Limit`, `X-RateLimit-Remaining`, `X-RateLimit-Reset`, dan `Retry-After`.",
            "content": {
              "application/json": {
                "examples": {
                  "Write rate limit exceeded": {
                    "summary": "Lebih dari 300 permintaan tulis pada menit ini",
                    "value": {
                      "detail": "Write request rate limit exceeded. You can make up to 300 requests per minute."
                    }
                  }
                },
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "202": {
            "description": "Laporan diterima dan masih diproses. Saat laporan masih disiapkan, endpoint mengembalikan 202 Accepted, kyb_registry.fetch_status=pending, dan registry_tier_delivered=null. Simpan request_id dan ambil GET /v3/session/{request_id}/decision/ hingga registry_checks[0].company.fetch_status terselesaikan. Didit menyelesaikan laporan secara otomatis dan mengenakan biaya untuk tingkat yang diberikan setelah siap. Jangan mengulangi pembelian saat masih tertunda; setiap POST baru membuat permintaan terpisah.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/paths/~1v3~1kyb~1shareholders~1/post/responses/200/content/application~1json/schema"
                },
                "examples": {
                  "Pending (registry still resolving)": {
                    "summary": "Laporan kepemilikan masih diproses; ambil keputusan yang tersimpan",
                    "value": {
                      "request_id": "9d4f2c7a-1b3e-4a5c-8d6f-0e9a8b7c6d5e",
                      "kyb_registry": {
                        "uuid": "7c0a4f7e-2b1d-4f6a-9c3e-8d5b2a1f0e9d",
                        "node_id": "feature_kyb_registry",
                        "status": "Not Finished",
                        "registry_status": null,
                        "data_resolved": false,
                        "company_name": "Example Holdings Limited",
                        "registration_number": "12345678",
                        "country_code": "HK",
                        "region": null,
                        "company_type": null,
                        "incorporation_date": null,
                        "registered_address": null,
                        "tax_number": null,
                        "risk_level": null,
                        "verification_status": null,
                        "is_from_registry": true,
                        "fetch_status": "pending",
                        "alternative_names": null,
                        "nature_of_business": null,
                        "registered_capital": null,
                        "registered_capital_amount": null,
                        "registered_capital_currency": null,
                        "website": null,
                        "email": null,
                        "phone": null,
                        "legal_entity_identifier": null,
                        "location_of_registration": null,
                        "financial_summary": {},
                        "officers": [],
                        "beneficial_owners": [],
                        "addresses": null,
                        "industries": null,
                        "accounts": null,
                        "registry_data": {},
                        "user_provided_data": null,
                        "confirmed_by_user_at": null,
                        "last_console_edit_at": null,
                        "is_editable": true,
                        "registry_tier_delivered": null,
                        "registry_ownership_status": "pending"
                      },
                      "vendor_data": "company-1234",
                      "metadata": null,
                      "created_at": "2026-06-11T10:45:00.000000+00:00",
                      "registry_tier_delivered": null,
                      "registry_tier_requested": "shareholders"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v3/kyb/ubo/": {
      "post": {
        "summary": "Perusahaan registri KYB dengan pemilik manfaat akhir (mandiri)",
        "operationId": "post_v3_kyb_ubo",
        "x-didit-sdk": {
          "resource": "kyb",
          "method": "list_ubos",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Standalone APIs"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [],
        "description": "Ambil profil Lite, pemegang saham langsung **dan pemilik manfaat akhir (UBO)** yang terselesaikan melalui rantai kepemilikan (`registry_data.ubo_resolution` memuat rantai induk perusahaan) dari satu kandidat yang dikembalikan oleh `POST /v3/kyb/search/`.\n\n**Penyandingan dengan pencarian.** Teruskan `kyb_response_id` kandidat persis seperti yang dikembalikan oleh pencarian pada aplikasi yang sama. Lakukan pencarian pada tingkat yang ingin Anda beli (`tier` pada `POST /v3/kyb/search/`), karena pencarian berjalan pada rantai registri yang melayani tingkat tersebut dan pencarian Lite yang kosong bukanlah bukti bahwa registri tidak memuat perusahaan tersebut. Ketika data kepemilikan negara tersebut berada di registri lain, Didit akan mencari ulang perusahaan di sana berdasarkan nomor registrasi, tanpa biaya tambahan.\n\n**Penagihan.** Ditagihkan sesuai harga UBO negara terkait - lihat [harga registri KYB](/id/getting-started/kyb-registry-pricing). Tingkat yang dikirimkan adalah yang tertinggi yang dapat dilayani oleh negara dan registri: Pemegang Saham ketika laporan yang terselesaikan tidak mencantumkan orang pribadi sebagai pemilik manfaat, Lite ketika tidak ada catatan kepemilikan sama sekali; `registry_tier_delivered` mencantumkan apa yang ditagihkan. Saldo diperiksa terhadap harga UBO sebelum panggilan registri apa pun (`403` jika kurang).\n\n**Ketersediaan.** Hanya v3. Setiap panggilan membuat sesi bisnis (id-nya adalah `request_id`).\n\n**Laporan yang tertunda.** Ketika laporan masih disiapkan, atau bagian kepemilikan belum diambil dari registri, endpoint mengembalikan 202 Accepted, kyb_registry.fetch_status=pending, kyb_registry.registry_ownership_status=pending, dan registry_tier_delivered=null. Simpan request_id dan panggil GET /v3/session/{request_id}/decision/ hingga registry_checks[0].company.fetch_status terselesaikan. Didit menyelesaikan laporan secara otomatis dan menagihkan tingkat yang terkirim setelah siap. Jangan mengulangi pembelian saat masih tertunda; setiap POST baru membuat permintaan terpisah.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/KYBRegistryCandidateRequest"
              },
              "example": {
                "kyb_response_id": "69aeeb95febb0f1704042259",
                "vendor_data": "company-1234"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST https://verification.didit.me/v3/kyb/ubo/ \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"kyb_response_id\": \"69aeeb95febb0f1704042259\",\n    \"vendor_data\": \"company-1234\"\n  }'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.kyb.list_ubos(\n    kyb_response_id=\"69aeeb95febb0f1704042259\",\n    vendor_data=\"company-1234\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.kyb.listUbos({\n  kyb_response_id: \"69aeeb95febb0f1704042259\",\n  vendor_data: \"company-1234\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.KYB.ListUBOs(ctx, didit.KYBRegistryCandidateRequest{\n\tKYBResponseID: \"69aeeb95febb0f1704042259\",\n\tVendorData:    didit.String(\"company-1234\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.KYBRegistryCandidateRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.kyb().listUbos(KYBRegistryCandidateRequest.builder()\n        .kybResponseId(\"69aeeb95febb0f1704042259\")\n        .vendorData(\"company-1234\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->kyb->listUbos([\n    'kyb_response_id' => '69aeeb95febb0f1704042259',\n    'vendor_data' => 'company-1234',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.kyb.list_ubos(\n  kyb_response_id: \"69aeeb95febb0f1704042259\",\n  vendor_data: \"company-1234\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Kyb.ListUbosAsync(new KYBRegistryCandidateRequest\n{\n    KybResponseId = \"69aeeb95febb0f1704042259\",\n    VendorData = \"company-1234\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "Laporan perusahaan dikembalikan dan ditagihkan pada tingkat yang diberikan. Laporan kepemilikan yang masih dipersiapkan dapat mengembalikan 202; simpan request_id untuk mengambil keputusan yang disimpan.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "request_id": {
                      "type": "string",
                      "format": "uuid",
                      "description": "ID sesi bisnis yang dibuat untuk pengambilan ini. Catatan yang disimpan (terlihat di konsol) terus diperbarui jika registri berhasil menyelesaikan pencarian setelah respons."
                    },
                    "registry_tier_requested": {
                      "type": "string",
                      "enum": [
                        "basic",
                        "shareholders",
                        "ubo"
                      ],
                      "description": "Tingkat yang dijual endpoint ini: `basic` (Lite) untuk opsi tertentu, `shareholders`, `ubo`."
                    },
                    "registry_tier_delivered": {
                      "type": "string",
                      "enum": [
                        "basic",
                        "shareholders",
                        "ubo",
                        null
                      ],
                      "description": "Tingkat yang benar-benar dikirimkan dan ditagihkan. Lebih rendah dari yang diminta jika registri negara tersebut tidak menyimpan data kepemilikan, jika registri tidak memiliki catatan kepemilikan untuk perusahaan ini, atau jika laporan terselesaikan dari permintaan `ubo` tidak menyebutkan orang pribadi sebagai pemilik manfaat.",
                      "nullable": true
                    },
                    "kyb_registry": {
                      "type": "object",
                      "description": "Profil perusahaan registri lengkap.",
                      "properties": {
                        "uuid": {
                          "type": "string",
                          "format": "uuid",
                          "description": "ID Didit untuk catatan perusahaan ini."
                        },
                        "node_id": {
                          "type": "string",
                          "example": "feature_kyb_registry"
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "Not Finished",
                            "Approved",
                            "Declined",
                            "In Review"
                          ],
                          "description": "Penilaian Didit atas pemeriksaan registri (misalnya `In Review` ketika perusahaan tidak aktif di registri atau data kepemilikan tidak dapat diturunkan)."
                        },
                        "registry_status": {
                          "type": "string",
                          "nullable": true,
                          "enum": [
                            "active",
                            "dissolved",
                            "deregistered",
                            "see full details",
                            "authorised",
                            "appointed representative",
                            "unauthorised",
                            "inactive",
                            "no longer authorised",
                            "closed",
                            "struck off",
                            null
                          ],
                          "description": "Status perusahaan yang dinormalisasi sebagaimana dilaporkan oleh registri."
                        },
                        "data_resolved": {
                          "type": "boolean",
                          "description": "`true` setelah registri mengembalikan profil lengkap. `false` jika registri masih memproses setelah polling — data yang disimpan akan selesai secara otomatis setelah registri selesai memproses."
                        },
                        "company_name": {
                          "type": "string",
                          "example": "Tesco PLC"
                        },
                        "registration_number": {
                          "type": "string",
                          "nullable": true,
                          "example": "00445790"
                        },
                        "country_code": {
                          "type": "string",
                          "description": "ISO 3166-1 alpha-2.",
                          "example": "GB"
                        },
                        "region": {
                          "type": "string",
                          "nullable": true,
                          "description": "Kode subdivisi jika registri bersifat regional (misalnya `CA` untuk `US-CA`); kosong jika tidak."
                        },
                        "company_type": {
                          "type": "string",
                          "nullable": true,
                          "example": "Public Limited Company"
                        },
                        "incorporation_date": {
                          "type": "string",
                          "format": "date",
                          "nullable": true,
                          "example": "1947-11-27"
                        },
                        "registered_address": {
                          "type": "string",
                          "nullable": true,
                          "example": "Tesco House, Shire Park, Kestrel Way, Welwyn Garden City, United Kingdom, AL7 1GA"
                        },
                        "tax_number": {
                          "type": "string",
                          "nullable": true,
                          "example": "GB412 8925 93"
                        },
                        "risk_level": {
                          "type": "string",
                          "nullable": true,
                          "description": "Tingkat risiko yang dilaporkan registri, jika tersedia."
                        },
                        "verification_status": {
                          "type": "string",
                          "enum": [
                            "verified",
                            "failed",
                            "unknown"
                          ],
                          "nullable": true,
                          "description": "Status verifikasi lintas yurisdiksi: `verified` ketika status registri menetapkan status hukum aktif (`active`), `failed` ketika menyatakan bahwa perusahaan tidak lagi berstatus baik (misalnya `dissolved`), jika tidak maka `unknown`. Bernilai `null` untuk perusahaan yang tidak berasal dari registri dan selama pemilihan masih `pending`."
                        },
                        "is_from_registry": {
                          "type": "boolean",
                          "description": "Selalu `true` untuk endpoint ini — profil diambil dari registri resmi."
                        },
                        "fetch_status": {
                          "type": "string",
                          "enum": [
                            "pending",
                            "resolved"
                          ],
                          "description": "Siklus hidup pengambilan registri. Dicerminkan oleh `data_resolved`."
                        },
                        "alternative_names": {
                          "type": "string",
                          "nullable": true,
                          "description": "Nama perusahaan alternatif, nama dagang, nama terdahulu, atau nama dalam bahasa asli sebagai teks, jika dilaporkan."
                        },
                        "nature_of_business": {
                          "type": "string",
                          "nullable": true,
                          "description": "Deskripsi aktivitas atau kode klasifikasi, jika dilaporkan."
                        },
                        "registered_capital": {
                          "type": "string",
                          "nullable": true
                        },
                        "registered_capital_amount": {
                          "type": "string",
                          "nullable": true,
                          "description": "Jumlah desimal sebagai string, saat dilaporkan."
                        },
                        "registered_capital_currency": {
                          "type": "string",
                          "nullable": true,
                          "description": "Kode ISO 4217, saat dilaporkan."
                        },
                        "website": {
                          "type": "string",
                          "nullable": true,
                          "example": "https://www.tesco.com/"
                        },
                        "email": {
                          "type": "string",
                          "nullable": true,
                          "example": "customer.service@tesco.co.uk"
                        },
                        "phone": {
                          "type": "string",
                          "nullable": true,
                          "example": "03301231688"
                        },
                        "legal_entity_identifier": {
                          "type": "string",
                          "nullable": true,
                          "description": "LEI, jika dilaporkan."
                        },
                        "location_of_registration": {
                          "type": "string",
                          "nullable": true,
                          "description": "Registri/yurisdiksi tempat perusahaan terdaftar, jika dilaporkan."
                        },
                        "vat_number": {
                          "type": "string",
                          "nullable": true,
                          "description": "Nomor PPN Uni Eropa, saat dikumpulkan selama langkah registri yang di-hosting atau diedit sesudahnya. Saat dipilih, nilai ini biasanya belum ditetapkan — validasi PPN dan ID pajak dijalankan ketika pengguna akhir mengirimkan langkah registri dalam alur yang di-hosting."
                        },
                        "vat_validation_status": {
                          "type": "string",
                          "enum": [
                            "valid",
                            "invalid",
                            "format_valid",
                            "invalid_format",
                            "could_not_validate",
                            "not_applicable"
                          ],
                          "description": "Hasil validasi nomor PPN atau, jika tidak ada, `tax_number`, saat pengiriman ke registri. `valid` / `invalid`: ditentukan oleh registri resmi negara (EU VIES, Norwegia, Swiss, Brasil, Kolombia, Kosta Rika, Ekuador, Paraguay; Polandia juga melalui registri PPN domestiknya). `format_valid` / `invalid_format`: ditentukan oleh aturan format dan digit centang negara tersebut jika tidak ada registri yang dapat dikueri. `could_not_validate`: registri tidak tersedia. `not_applicable`: tidak ada nomor, negara tanpa registri atau aturan, atau sesi sandbox."
                        },
                        "vat_validated_number": {
                          "type": "string",
                          "nullable": true,
                          "description": "Nomor yang diperiksa, sebagaimana diketahui oleh sumber (misalnya nomor PPN yang diperoleh dari SIREN Prancis atau RSIN Belanda). `null` jika tidak ada pemeriksaan yang dijalankan."
                        },
                        "vat_validation_source": {
                          "type": "string",
                          "nullable": true,
                          "enum": [
                            "eu_vies",
                            "pl_vat_white_list",
                            "no_brreg",
                            "ch_uid_register",
                            "br_receita_federal",
                            "co_rues",
                            "cr_hacienda",
                            "ec_sri",
                            "py_dnit",
                            "format_rules",
                            null
                          ],
                          "description": "Sumber yang menentukan `vat_validation_status`: registri resmi, atau `format_rules`. `null` jika tidak ada pemeriksaan yang dijalankan."
                        },
                        "vat_validated_name": {
                          "type": "string",
                          "nullable": true,
                          "description": "Nama yang terdaftar pada sumber yang memvalidasi nomor tersebut, jika menyediakannya. Hanya ditetapkan saat statusnya `valid`."
                        },
                        "vat_validated_address": {
                          "type": "string",
                          "nullable": true,
                          "description": "Alamat yang terdaftar pada sumber yang memvalidasi nomor tersebut, jika sumber mengungkapkannya. Hanya diisi jika statusnya `valid`."
                        },
                        "vat_checked_at": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true,
                          "description": "Cap waktu pemeriksaan. `null` jika tidak ada pemeriksaan yang dilakukan."
                        },
                        "financial_summary": {
                          "type": "object",
                          "nullable": true,
                          "description": "Detail saham/modal yang dilaporkan registri (mata uang, total saham, kelas saham), jika tersedia."
                        },
                        "officers": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "uuid": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "name": {
                                "type": "string",
                                "example": "MELISSA BETHELL"
                              },
                              "designation": {
                                "type": "string",
                                "nullable": true,
                                "description": "Penetapan registri mentah (misalnya `Director`, `Secretary`)."
                              },
                              "role": {
                                "type": "string",
                                "description": "Peran yang dinormalisasi yang diturunkan dari sebutan. Kumpulan model 17 nilai lengkap; penguraian registri pada endpoint ini biasanya menghasilkan director, non_executive_director, secretary, chairman, atau company_officer.",
                                "enum": [
                                  "director",
                                  "non_executive_director",
                                  "secretary",
                                  "chairman",
                                  "ubo",
                                  "shareholder",
                                  "representative",
                                  "founder",
                                  "legal_advisor",
                                  "authorized_signatory",
                                  "trustee",
                                  "beneficiary",
                                  "company_officer",
                                  "settlor",
                                  "protector",
                                  "investor",
                                  "other"
                                ]
                              },
                              "nationality": {
                                "type": "string",
                                "nullable": true
                              },
                              "is_active": {
                                "type": "boolean",
                                "description": "`false` saat registri menandai pengangkatan telah berakhir karena pengunduran diri."
                              },
                              "kyc_status": {
                                "type": "string",
                                "nullable": true,
                                "enum": [
                                  "Approved",
                                  "Declined",
                                  "Pending",
                                  null
                                ],
                                "description": "Status sesi KYC terkait, jika ada yang dimulai untuk pejabat ini. Jika tidak, bernilai `null`."
                              },
                              "kyc_session_url": {
                                "type": "string",
                                "nullable": true,
                                "description": "URL verifikasi dari sesi KYC terkait, jika ada."
                              },
                              "first_name": {
                                "type": "string",
                                "nullable": true,
                                "description": "Nama depan ketika dilaporkan secara eksplisit oleh registri; tidak disimpulkan dari nama lengkap."
                              },
                              "last_name": {
                                "type": "string",
                                "nullable": true,
                                "description": "Nama keluarga ketika dilaporkan secara eksplisit oleh registri."
                              },
                              "address": {
                                "type": "string",
                                "nullable": true,
                                "description": "Alamat pejabat yang dilaporkan oleh registri."
                              },
                              "appointment_date": {
                                "type": "string",
                                "nullable": true,
                                "description": "Tanggal petugas diangkat.",
                                "format": "date"
                              },
                              "termination_date": {
                                "type": "string",
                                "nullable": true,
                                "description": "Tanggal pengangkatan berakhir, jika dilaporkan.",
                                "format": "date"
                              },
                              "date_of_birth": {
                                "type": "string",
                                "nullable": true,
                                "description": "Tanggal lahir lengkap yang dilaporkan registri. Bernilai null jika hanya tahun atau bulan lahir yang diketahui.",
                                "format": "date"
                              },
                              "date_of_birth_year": {
                                "type": "integer",
                                "nullable": true,
                                "minimum": 1,
                                "maximum": 9999,
                                "description": "Tahun lahir yang dilaporkan registri, termasuk saat tanggal lengkap tidak tersedia."
                              },
                              "date_of_birth_month": {
                                "type": "integer",
                                "nullable": true,
                                "minimum": 1,
                                "maximum": 12,
                                "description": "Bulan lahir yang dilaporkan registri. Null jika hanya tahun yang diketahui."
                              }
                            }
                          },
                          "description": "Direktur, sekretaris, dan petugas lainnya yang diekstrak dari registri."
                        },
                        "beneficial_owners": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "uuid": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "name": {
                                "type": "string"
                              },
                              "first_name": {
                                "type": "string",
                                "nullable": true
                              },
                              "last_name": {
                                "type": "string",
                                "nullable": true
                              },
                              "entity_type": {
                                "type": "string",
                                "enum": [
                                  "person",
                                  "company"
                                ],
                                "description": "Apakah pemiliknya adalah perorangan atau entitas korporat."
                              },
                              "roles": {
                                "type": "array",
                                "items": {
                                  "type": "string"
                                },
                                "description": "Peran yang dinormalisasi (misalnya `ubo`, `shareholder`)."
                              },
                              "ownership_min_shares": {
                                "type": "string",
                                "nullable": true,
                                "description": "Batas bawah rentang kepemilikan yang dilaporkan oleh registri (misalnya `25%`)."
                              },
                              "ownership_max_shares": {
                                "type": "string",
                                "nullable": true,
                                "description": "Batas atas rentang kepemilikan yang dilaporkan oleh registri."
                              },
                              "is_active": {
                                "type": "boolean"
                              },
                              "kyc_status": {
                                "type": "string",
                                "nullable": true,
                                "enum": [
                                  "Approved",
                                  "Declined",
                                  "Pending",
                                  null
                                ]
                              },
                              "kyc_session_url": {
                                "type": "string",
                                "nullable": true
                              },
                              "effective_ownership_percent": {
                                "type": "number",
                                "nullable": true,
                                "description": "Persentase kepemilikan terurai (batas maksimum, beralih ke batas minimum jika tidak ada)."
                              },
                              "company_name": {
                                "type": "string",
                                "nullable": true
                              },
                              "registration_number": {
                                "type": "string",
                                "nullable": true
                              },
                              "country_of_birth": {
                                "type": "string",
                                "nullable": true
                              },
                              "email": {
                                "type": "string",
                                "nullable": true
                              },
                              "nationality": {
                                "type": "string",
                                "nullable": true
                              },
                              "designation": {
                                "type": "string",
                                "nullable": true
                              },
                              "voting_min_shares": {
                                "type": "string",
                                "nullable": true
                              },
                              "voting_max_shares": {
                                "type": "string",
                                "nullable": true
                              },
                              "date_of_birth": {
                                "type": "string",
                                "nullable": true,
                                "description": "Tanggal lahir lengkap jika dilaporkan.",
                                "format": "date"
                              },
                              "appointment_date": {
                                "type": "string",
                                "nullable": true,
                                "description": "Tanggal penunjukan saat dilaporkan.",
                                "format": "date"
                              },
                              "shareholding": {
                                "$ref": "#/components/schemas/KYBRegistryShareholding"
                              }
                            }
                          },
                          "description": "Pemilik manfaat / pihak dengan kendali signifikan yang diekstrak dari registri. Dapat bernilai kosong jika registri tidak mencantumkan kepemilikan."
                        },
                        "addresses": {
                          "type": "array",
                          "nullable": true,
                          "description": "Setiap alamat yang dinyatakan oleh registri, satu bentuk kanonikal. Null jika tidak ada yang dinyatakan.",
                          "items": {
                            "$ref": "#/components/schemas/KYBRegistryAddress"
                          }
                        },
                        "industries": {
                          "type": "array",
                          "nullable": true,
                          "description": "Aktivitas yang diklasifikasikan oleh registri untuk perusahaan, dalam satu format kanonis. Bernilai null jika tidak ada yang dinyatakan.",
                          "items": {
                            "$ref": "#/components/schemas/KYBRegistryIndustry"
                          }
                        },
                        "accounts": {
                          "type": "object",
                          "nullable": true,
                          "additionalProperties": true,
                          "description": "Tanggal pengajuan registri, jika tersedia. Laporan tahunan dan rapat umum menggunakan last_annual_return_date dan last_agm_date; keduanya berbeda dari laporan keuangan."
                        },
                        "registry_data": {
                          "$ref": "#/components/schemas/KYBRegistryData"
                        },
                        "user_provided_data": {
                          "type": "object",
                          "nullable": true,
                          "description": "Selalu `null` pada endpoint ini (digunakan oleh alur KYB yang di-hosting saat pengguna akhir mengedit data registri)."
                        },
                        "confirmed_by_user_at": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true,
                          "description": "Selalu `null` pada endpoint ini."
                        },
                        "last_console_edit_at": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true,
                          "description": "Ditetapkan saat peninjau konsol mengedit catatan tersebut nanti."
                        },
                        "is_editable": {
                          "type": "boolean",
                          "description": "Apakah data yang bersumber dari registri masih dapat diedit di alur yang di-hosting atau di konsol."
                        },
                        "registry_tier_delivered": {
                          "type": "string",
                          "enum": [
                            "basic",
                            "shareholders",
                            "ubo",
                            null
                          ],
                          "description": "Sama dengan `registry_tier_delivered` di tingkat teratas.",
                          "nullable": true
                        },
                        "registry_ownership_status": {
                          "type": "string",
                          "nullable": true,
                          "enum": [
                            "not_requested",
                            "delivered",
                            "not_held",
                            "unavailable",
                            "pending",
                            null
                          ],
                          "description": "`delivered` saat data kepemilikan berhasil diperoleh, `not_held` saat registri kepemilikan merespons dan tidak mencantumkan perusahaan ini (lihat `registry_data.ownership_error`), `unavailable` saat tingkat kepemilikan diminta tetapi registri tidak memilikinya untuk perusahaan ini atau tidak dapat dimintai keterangan (lihat `registry_data.ownership_error`), `pending` saat bagian kepemilikan belum diambil dari registri dan Didit masih menyelesaikannya, `not_requested` pada tingkat Lite."
                        },
                        "ownership": {
                          "$ref": "#/components/schemas/KYBRegistryOwnership"
                        },
                        "registry_tier": {
                          "type": "string",
                          "nullable": true,
                          "description": "Tingkat registri yang dipesan oleh alur kerja: `basic`, `shareholders`, atau `ubo`. Juga terdapat di `ownership.tier_requested`."
                        },
                        "registry_monitoring": {
                          "type": "object",
                          "nullable": true,
                          "description": "Pemantau registri terbaru untuk perusahaan, atau `null` jika tidak ada.",
                          "properties": {
                            "uuid": {
                              "type": "string",
                              "format": "uuid"
                            },
                            "status": {
                              "type": "string"
                            },
                            "unavailable_reason": {
                              "type": "string",
                              "nullable": true
                            },
                            "enrolled_at": {
                              "type": "string",
                              "format": "date-time",
                              "nullable": true
                            },
                            "cancelled_at": {
                              "type": "string",
                              "format": "date-time",
                              "nullable": true
                            },
                            "last_bill_date": {
                              "type": "string",
                              "format": "date",
                              "nullable": true
                            },
                            "next_bill_date": {
                              "type": "string",
                              "format": "date",
                              "nullable": true
                            },
                            "last_event_at": {
                              "type": "string",
                              "format": "date-time",
                              "nullable": true
                            },
                            "events_count": {
                              "type": "integer"
                            },
                            "watched_fields": {
                              "description": "Kolom perusahaan yang dipantau oleh pemantau."
                            }
                          }
                        }
                      }
                    },
                    "vendor_data": {
                      "type": "string",
                      "nullable": true,
                      "description": "Menampilkan kembali `vendor_data` yang Anda kirimkan."
                    },
                    "metadata": {
                      "type": "object",
                      "nullable": true,
                      "description": "Salinan `metadata` yang Anda kirimkan."
                    },
                    "created_at": {
                      "type": "string",
                      "format": "date-time"
                    }
                  }
                },
                "examples": {
                  "Resolved company": {
                    "summary": "Profil registri lengkap (daftar pejabat dipersingkat untuk menghemat tempat)",
                    "value": {
                      "request_id": "9d4f2c7a-1b3e-4a5c-8d6f-0e9a8b7c6d5e",
                      "kyb_registry": {
                        "uuid": "f1e2d3c4-b5a6-4789-9c0d-1e2f3a4b5c6d",
                        "node_id": "feature_kyb_registry",
                        "status": "In Review",
                        "registry_status": "active",
                        "data_resolved": true,
                        "company_name": "Tesco PLC",
                        "registration_number": "00445790",
                        "country_code": "GB",
                        "region": "",
                        "company_type": "Public Limited Company",
                        "incorporation_date": "1947-11-27",
                        "registered_address": "Tesco House, Shire Park, Kestrel Way, Welwyn Garden City, United Kingdom, AL7 1GA",
                        "tax_number": "GB412 8925 93",
                        "risk_level": "low risk",
                        "verification_status": "verified",
                        "is_from_registry": true,
                        "fetch_status": "resolved",
                        "alternative_names": "TESCO STORES (HOLDINGS) PUBLIC LIMITED COMPANY",
                        "nature_of_business": null,
                        "registered_capital": null,
                        "registered_capital_amount": null,
                        "registered_capital_currency": null,
                        "website": "https://www.tesco.com/",
                        "email": "customer.service@tesco.co.uk",
                        "phone": "03301231688",
                        "legal_entity_identifier": null,
                        "location_of_registration": null,
                        "financial_summary": {
                          "currency": "Pound (£)",
                          "total_number_of_shares": "8174378721",
                          "meta_detail": {
                            "Class_Of_Share": "Ordinary"
                          }
                        },
                        "officers": [
                          {
                            "uuid": "a1b2c3d4-e5f6-4789-9a0b-1c2d3e4f5a6b",
                            "name": "CHRISTOPHER JON TAYLOR",
                            "designation": "Secretary",
                            "role": "secretary",
                            "nationality": null,
                            "is_active": true,
                            "kyc_status": null,
                            "kyc_session_url": null
                          },
                          {
                            "uuid": "b2c3d4e5-f6a7-4890-8b1c-2d3e4f5a6b7c",
                            "name": "MELISSA BETHELL",
                            "designation": "Director",
                            "role": "director",
                            "nationality": "British",
                            "is_active": true,
                            "kyc_status": null,
                            "kyc_session_url": null
                          }
                        ],
                        "beneficial_owners": [],
                        "addresses": [
                          {
                            "address": "Tesco House, Shire Park, Kestrel Way, Welwyn Garden City, United Kingdom, AL7 1GA",
                            "type": "legal_entity_registry_address",
                            "description": "registered office address"
                          }
                        ],
                        "industries": null,
                        "accounts": {
                          "last_account": "26 February 2025",
                          "next_account": "26 February 2026",
                          "due_by_date": "26 August 2026"
                        },
                        "registry_data": {
                          "ubo_resolution": {
                            "parent_chain": [],
                            "subsidiaries": [],
                            "unresolved": []
                          }
                        },
                        "user_provided_data": null,
                        "confirmed_by_user_at": null,
                        "last_console_edit_at": null,
                        "is_editable": true
                      },
                      "vendor_data": "company-1234",
                      "metadata": null,
                      "created_at": "2026-06-11T10:45:00.000000+00:00"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Kesalahan validasi. Masalah tingkat kolom menggunakan format standar DRF.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing kyb_response_id": {
                    "summary": "`kyb_response_id` diperlukan",
                    "value": {
                      "kyb_response_id": [
                        "This field is required."
                      ]
                    }
                  },
                  "save_api_request=false rejected": {
                    "summary": "Pilihan selalu disimpan",
                    "value": {
                      "save_api_request": [
                        "KYB registry select must be saved so billing and retrieval can be tracked."
                      ]
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Izin ditolak. Dikembalikan ketika header `x-api-key` tidak ada, dan juga ketika saldo organisasi pemanggil tidak dapat mencukupi biaya panggilan tersebut; kunci yang salah, dicabut, atau kedaluwarsa mengembalikan `401`. Kunci yang tidak ada mengembalikan `403` dengan `{\"detail\": ...}`; kunci yang salah, dicabut, atau kedaluwarsa mengembalikan `401`. Kekurangan kredit mengembalikan `403` dengan `{\"error\": ...}` sebelum skrining atau panggilan penyedia apa pun terjadi.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing or invalid API key": {
                    "summary": "Tidak ada header `x-api-key`, atau kuncinya tidak valid/dicabut",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Not enough credits": {
                    "summary": "Saldo organisasi tidak mencukupi untuk panggilan ini",
                    "value": {
                      "error": "You don't have enough credits to perform this request. Please top up at https://business.didit.me"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Batas laju terlampaui. Endpoint POST/PATCH/DELETE berbagi anggaran 300 permintaan penulisan per menit per kunci API (pembuatan transaksi dan ingesti event memiliki anggaran terpisah sebesar 600). Respons menyertakan header `X-RateLimit-Limit`, `X-RateLimit-Remaining`, `X-RateLimit-Reset`, dan `Retry-After`.",
            "content": {
              "application/json": {
                "examples": {
                  "Write rate limit exceeded": {
                    "summary": "Lebih dari 300 permintaan tulis pada menit ini",
                    "value": {
                      "detail": "Write request rate limit exceeded. You can make up to 300 requests per minute."
                    }
                  }
                },
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "202": {
            "description": "Laporan diterima dan masih diproses. Saat laporan masih disiapkan, endpoint mengembalikan 202 Accepted, kyb_registry.fetch_status=pending, dan registry_tier_delivered=null. Simpan request_id dan ambil GET /v3/session/{request_id}/decision/ hingga registry_checks[0].company.fetch_status terselesaikan. Didit menyelesaikan laporan secara otomatis dan mengenakan biaya untuk tingkat yang diberikan setelah siap. Jangan mengulangi pembelian saat masih tertunda; setiap POST baru membuat permintaan terpisah.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/paths/~1v3~1kyb~1ubo~1/post/responses/200/content/application~1json/schema"
                },
                "examples": {
                  "Pending (registry still resolving)": {
                    "summary": "Laporan kepemilikan masih diproses; ambil keputusan yang tersimpan",
                    "value": {
                      "request_id": "9d4f2c7a-1b3e-4a5c-8d6f-0e9a8b7c6d5e",
                      "kyb_registry": {
                        "uuid": "7c0a4f7e-2b1d-4f6a-9c3e-8d5b2a1f0e9d",
                        "node_id": "feature_kyb_registry",
                        "status": "Not Finished",
                        "registry_status": null,
                        "data_resolved": false,
                        "company_name": "Example Holdings Limited",
                        "registration_number": "12345678",
                        "country_code": "HK",
                        "region": null,
                        "company_type": null,
                        "incorporation_date": null,
                        "registered_address": null,
                        "tax_number": null,
                        "risk_level": null,
                        "verification_status": null,
                        "is_from_registry": true,
                        "fetch_status": "pending",
                        "alternative_names": null,
                        "nature_of_business": null,
                        "registered_capital": null,
                        "registered_capital_amount": null,
                        "registered_capital_currency": null,
                        "website": null,
                        "email": null,
                        "phone": null,
                        "legal_entity_identifier": null,
                        "location_of_registration": null,
                        "financial_summary": {},
                        "officers": [],
                        "beneficial_owners": [],
                        "addresses": null,
                        "industries": null,
                        "accounts": null,
                        "registry_data": {},
                        "user_provided_data": null,
                        "confirmed_by_user_at": null,
                        "last_console_edit_at": null,
                        "is_editable": true,
                        "registry_tier_delivered": null,
                        "registry_ownership_status": "pending"
                      },
                      "vendor_data": "company-1234",
                      "metadata": null,
                      "created_at": "2026-06-11T10:45:00.000000+00:00",
                      "registry_tier_delivered": null,
                      "registry_tier_requested": "ubo"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v3/id-verification/wallets/": {
      "get": {
        "operationId": "list_wallets",
        "x-didit-sdk": {
          "resource": "id_wallets",
          "method": "list",
          "auth": "api_key",
          "server": true
        },
        "description": "Setiap dompet ID Digital beserta endpoint mulainya, negara, kolom yang diperlukan, dan apakah aplikasi ini dapat memulainya di lingkungan ini sekarang. Terdaftar bukan berarti aktif.",
        "summary": "Daftar dompet Digital ID",
        "tags": [
          "Digital ID wallets"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          },
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletCatalogResponse"
                }
              }
            },
            "description": ""
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiClientCredentialsForbiddenErrorMessage"
                }
              }
            },
            "description": "Kredensial tidak ada (x-api-key atau Authorization: Bearer)."
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL",
            "source": "curl --request GET \\\n  --url https://verification.didit.me/v3/id-verification/wallets/ \\\n  --header 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.id_wallets.list()\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.idWallets.list();\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.IDWallets.List(ctx)\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.idWallets().list();\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->idWallets->list();\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.id_wallets.list\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.IdWallets.ListAsync();\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/id-verification/wallets/verifications/{request_id}/": {
      "get": {
        "operationId": "get_wallet_verification",
        "x-didit-sdk": {
          "resource": "id_wallets",
          "method": "retrieve_verification",
          "auth": "api_key",
          "server": true
        },
        "description": "Status dan hasil verifikasi dompet: identitas yang dinormalisasi dan atribut dompet itu sendiri setelah diverifikasi, kode kesalahan setelah ditolak, tindakan berikutnya saat tertunda. Verifikasi yang melewati expires_at ditetapkan sebagai timeout.",
        "summary": "Dapatkan verifikasi dompet",
        "parameters": [
          {
            "in": "path",
            "name": "request_id",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "request_id yang dikembalikan oleh endpoint untuk memulai.",
            "required": true
          }
        ],
        "tags": [
          "Digital ID wallets"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          },
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationResponse"
                },
                "example": {
                  "request_id": "00000000-0000-4000-8000-000000000001",
                  "wallet_verification": {
                    "wallet": {
                      "id": "ftn",
                      "name": "Finnish Trust Network",
                      "issuing_authority": "Finnish banks and mobile operators (FTN)"
                    },
                    "country": "FIN",
                    "status": "Not Finished",
                    "outcome": "pending",
                    "error": null,
                    "interaction": "redirect",
                    "simulated": false,
                    "expires_at": "2026-01-01T10:10:00Z",
                    "next_action": {
                      "type": "redirect",
                      "url": "https://wallet.example.com/authorize"
                    },
                    "identity": null,
                    "attributes": null,
                    "level_of_assurance": null,
                    "verified_at": null,
                    "signature_valid": null,
                    "credential_type": "person_identification"
                  },
                  "vendor_data": "your-customer-reference",
                  "metadata": {
                    "reference": "example"
                  },
                  "created_at": "2026-01-01T10:00:00Z"
                }
              }
            },
            "description": ""
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiClientCredentialsForbiddenErrorMessage"
                }
              }
            },
            "description": "Kredensial tidak ada (x-api-key atau Authorization: Bearer)."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "kesalahan not_found: tidak ada verifikasi dompet dari aplikasi ini yang memiliki request_id ini."
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL",
            "source": "curl --request GET \\\n  --url https://verification.didit.me/v3/id-verification/wallets/verifications/REQUEST_ID/ \\\n  --header 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.id_wallets.retrieve_verification(\n    \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.idWallets.retrieveVerification(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.IDWallets.RetrieveVerification(ctx, \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.idWallets().retrieveVerification(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->idWallets->retrieveVerification('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.id_wallets.retrieve_verification(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.IdWallets.RetrieveVerificationAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/id-verification/wallets/verifications/{request_id}/poll/": {
      "post": {
        "operationId": "poll_wallet_verification",
        "x-didit-sdk": {
          "resource": "id_wallets",
          "method": "poll_verification",
          "auth": "api_key",
          "server": true
        },
        "description": "Smart-ID dan Mobile-ID: minta penyedia mengonfirmasi apakah pengguna mengonfirmasi, menolak, atau membiarkan prompt kedaluwarsa, dan verifikasi identitas yang ditandatangani saat mereka mengonfirmasi. Dompet pengalihan menyelesaikan proses melalui browser pengguna, sehingga untuk dompet tersebut panggilan ini hanya membaca kembali verifikasi. Mengembalikan verifikasi apa adanya setelahnya.",
        "summary": "Lakukan polling verifikasi dompet",
        "parameters": [
          {
            "in": "path",
            "name": "request_id",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "request_id yang dikembalikan oleh endpoint untuk memulai.",
            "required": true
          }
        ],
        "tags": [
          "Digital ID wallets"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          },
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationResponse"
                },
                "example": {
                  "request_id": "00000000-0000-4000-8000-000000000001",
                  "wallet_verification": {
                    "wallet": {
                      "id": "smart_id",
                      "name": "Smart-ID",
                      "issuing_authority": "SK ID Solutions"
                    },
                    "country": "EST",
                    "status": "Not Finished",
                    "outcome": "pending",
                    "error": null,
                    "interaction": "in_app",
                    "simulated": true,
                    "expires_at": "2026-01-01T10:10:00Z",
                    "next_action": {
                      "type": "confirm_in_app",
                      "verification_code": "1234",
                      "poll_interval_seconds": 2
                    },
                    "identity": null,
                    "attributes": null,
                    "level_of_assurance": null,
                    "verified_at": null,
                    "signature_valid": null,
                    "credential_type": "person_identification"
                  },
                  "vendor_data": "your-customer-reference",
                  "metadata": {
                    "reference": "example"
                  },
                  "created_at": "2026-01-01T10:00:00Z"
                }
              }
            },
            "description": ""
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiClientCredentialsForbiddenErrorMessage"
                }
              }
            },
            "description": "Kredensial tidak ada (x-api-key atau Authorization: Bearer)."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "kesalahan not_found: tidak ada verifikasi dompet dari aplikasi ini yang memiliki request_id ini."
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "kesalahan wallet_not_configured: lingkungan ini tidak dapat menjangkau dompet."
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL",
            "source": "curl --request POST \\\n  --url https://verification.didit.me/v3/id-verification/wallets/verifications/REQUEST_ID/poll/ \\\n  --header 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.id_wallets.poll_verification(\n    \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.idWallets.pollVerification(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.IDWallets.PollVerification(ctx, \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.idWallets().pollVerification(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->idWallets->pollVerification('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.id_wallets.poll_verification(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.IdWallets.PollVerificationAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/id-verification/wallets/verifications/{request_id}/cancel/": {
      "post": {
        "operationId": "cancel_wallet_verification",
        "x-didit-sdk": {
          "resource": "id_wallets",
          "method": "cancel_verification",
          "auth": "api_key",
          "server": true
        },
        "description": "Tarik verifikasi yang tertunda: verifikasi ditolak sebagai dibatalkan dan tidak pernah ditagih. Verifikasi yang sudah diputuskan dikembalikan tanpa perubahan. Smart-ID dan Mobile-ID: pembatalan yang tiba saat polling sedang memeriksa proses masuk akan menunggu beberapa detik untuk polling tersebut, lalu menolaknya, atau mengembalikannya terverifikasi jika pengguna telah mengonfirmasi. Verifikasi yang sedang diselesaikan pengguna saat ini tidak dapat dibatalkan (409 verification_in_progress dengan Retry-After): coba lagi setelah jumlah detik tersebut untuk membaca hasilnya.",
        "summary": "Batalkan verifikasi dompet",
        "parameters": [
          {
            "in": "path",
            "name": "request_id",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "request_id yang dikembalikan oleh endpoint untuk memulai.",
            "required": true
          }
        ],
        "tags": [
          "Digital ID wallets"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          },
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationResponse"
                },
                "example": {
                  "request_id": "00000000-0000-4000-8000-000000000001",
                  "wallet_verification": {
                    "wallet": {
                      "id": "ftn",
                      "name": "Finnish Trust Network",
                      "issuing_authority": "Finnish banks and mobile operators (FTN)"
                    },
                    "country": "FIN",
                    "status": "Declined",
                    "outcome": "cancelled",
                    "error": "cancelled_by_customer",
                    "interaction": "redirect",
                    "simulated": false,
                    "expires_at": "2026-01-01T10:10:00Z",
                    "next_action": null,
                    "identity": null,
                    "attributes": null,
                    "level_of_assurance": null,
                    "verified_at": null,
                    "signature_valid": null,
                    "credential_type": "person_identification"
                  },
                  "vendor_data": "your-customer-reference",
                  "metadata": {
                    "reference": "example"
                  },
                  "created_at": "2026-01-01T10:00:00Z"
                }
              }
            },
            "description": ""
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiClientCredentialsForbiddenErrorMessage"
                }
              }
            },
            "description": "Kredensial tidak ada (x-api-key atau Authorization: Bearer)."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "kesalahan not_found: tidak ada verifikasi dompet dari aplikasi ini yang memiliki request_id ini."
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "kesalahan verification_in_progress: pengguna sedang menyelesaikan proses masuk ini sekarang. Header Retry-After memberi tahu kapan harus mencoba lagi; percobaan ulang mengembalikan verifikasi yang telah diputuskan."
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL",
            "source": "curl --request POST \\\n  --url https://verification.didit.me/v3/id-verification/wallets/verifications/REQUEST_ID/cancel/ \\\n  --header 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.id_wallets.cancel_verification(\n    \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.idWallets.cancelVerification(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.IDWallets.CancelVerification(ctx, \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.idWallets().cancelVerification(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->idWallets->cancelVerification('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.id_wallets.cancel_verification(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.IdWallets.CancelVerificationAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/id-verification/wallets/mitid/": {
      "post": {
        "operationId": "start_mitid_wallet_verification",
        "x-didit-sdk": {
          "resource": "id_wallets",
          "method": "start_mitid",
          "auth": "api_key",
          "server": true
        },
        "description": "Mulai proses masuk MitID (Danish Agency for Digital Government; DNK) tanpa alur kerja apa pun. Ditagih sekali, hanya ketika identitas diverifikasi. Respons membawa next_action.type=redirect dengan URL tujuan browser pengguna; pengguna kembali ke return_url dengan request_id dan result yang ditambahkan. Baca hasilnya dengan GET /v3/id-verification/wallets/verifications/{request_id}/ atau dari webhook, jangan pernah dari URL. Aplikasi sandbox mendapatkan simulasi deterministik (simulated: true) yang tidak pernah menghubungi penyedia.",
        "summary": "Mulai verifikasi MitID",
        "parameters": [
          {
            "in": "header",
            "name": "Idempotency-Key",
            "schema": {
              "type": "string"
            },
            "description": "Kunci keamanan coba lagi opsional (maks 255 karakter). Mencoba lagi dengan kunci, dompet, dan body yang sama akan mengembalikan verifikasi asli tanpa memulai proses masuk kedua; kunci yang sama dengan dompet atau body lain akan mengembalikan 409 idempotency_key_reused."
          }
        ],
        "tags": [
          "Digital ID wallets"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiMitidWalletVerificationStartRequest"
              },
              "example": {
                "country": "DNK",
                "vendor_data": "your-customer-reference",
                "metadata": {
                  "reference": "example"
                },
                "return_url": "https://app.example.com/identity/complete"
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiMitidWalletVerificationStartRequest"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiMitidWalletVerificationStartRequest"
              }
            }
          },
          "required": true
        },
        "security": [
          {
            "ApiKeyAuth": []
          },
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationResponse"
                },
                "example": {
                  "request_id": "00000000-0000-4000-8000-000000000001",
                  "wallet_verification": {
                    "wallet": {
                      "id": "mitid",
                      "name": "MitID",
                      "issuing_authority": "Danish Agency for Digital Government"
                    },
                    "country": "DNK",
                    "status": "Not Finished",
                    "outcome": "pending",
                    "error": null,
                    "interaction": "redirect",
                    "simulated": false,
                    "expires_at": "2026-01-01T10:10:00Z",
                    "next_action": {
                      "type": "redirect",
                      "url": "https://wallet.example.com/authorize"
                    },
                    "identity": null,
                    "attributes": null,
                    "level_of_assurance": null,
                    "verified_at": null,
                    "signature_valid": null,
                    "credential_type": "person_identification"
                  },
                  "vendor_data": "your-customer-reference",
                  "metadata": {
                    "reference": "example"
                  },
                  "created_at": "2026-01-01T10:00:00Z"
                }
              }
            },
            "description": ""
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationStartBadRequest"
                }
              }
            },
            "description": "Error validasi kolom ({field: [messages]}), atau error return_url_invalid, return_url_not_allowed, invalid_personal_code, invalid_phone_number, atau idempotency_key_invalid."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationStartForbidden"
                }
              }
            },
            "description": "Kredensial tidak ada ({detail}), atau kesalahan wallet_unavailable, insufficient_credits, atau contract_rate_missing."
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "kesalahan idempotency_key_reused atau idempotency_key_in_progress (dengan Retry-After)."
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "kesalahan wallet_provider_unavailable: penyedia tidak dapat memulai; tidak ada yang dibuat."
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "kesalahan wallet_not_configured: lingkungan ini tidak dapat menjangkau dompet."
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL",
            "source": "curl --request POST \\\n  --url https://verification.didit.me/v3/id-verification/wallets/mitid/ \\\n  --header 'x-api-key: YOUR_API_KEY' \\\n  --header 'Idempotency-Key: your-unique-attempt-key' \\\n  --header 'Content-Type: application/json' \\\n  --data '{\n  \"country\": \"DNK\",\n  \"vendor_data\": \"your-customer-reference\",\n  \"metadata\": {\n    \"reference\": \"example\"\n  },\n  \"return_url\": \"https://app.example.com/identity/complete\"\n}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.id_wallets.start_mitid(\n    vendor_data=\"your-customer-reference\",\n    metadata={\"reference\": \"example\"},\n    country=\"DNK\",\n    return_url=\"https://app.example.com/identity/complete\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.idWallets.startMitid({\n  vendor_data: \"your-customer-reference\",\n  metadata: { reference: \"example\" },\n  country: \"DNK\",\n  return_url: \"https://app.example.com/identity/complete\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.IDWallets.StartMitid(ctx, didit.IDWalletsStartMitidParams{\n\tBody: didit.DigitalIDWalletAPIMitidWalletVerificationStartRequest{\n\t\tVendorData: didit.String(\"your-customer-reference\"),\n\t\tMetadata:   didit.Some(map[string]any{\"reference\": \"example\"}),\n\t\tCountry:    didit.Some(didit.DigitalIDWalletAPIMitidWalletVerificationStartCountryEnum(\"DNK\")),\n\t\tReturnURL:  \"https://app.example.com/identity/complete\",\n\t},\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.DigitalIdWalletApiMitidWalletVerificationStartCountryEnum;\nimport me.didit.types.DigitalIdWalletApiMitidWalletVerificationStartRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.idWallets().startMitid(DigitalIdWalletApiMitidWalletVerificationStartRequest.builder()\n        .vendorData(\"your-customer-reference\")\n        .metadata(Map.of(\"reference\", \"example\"))\n        .country(DigitalIdWalletApiMitidWalletVerificationStartCountryEnum.of(\"DNK\"))\n        .returnUrl(\"https://app.example.com/identity/complete\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->idWallets->startMitid([\n    'vendor_data' => 'your-customer-reference',\n    'metadata' => ['reference' => 'example'],\n    'country' => 'DNK',\n    'return_url' => 'https://app.example.com/identity/complete',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.id_wallets.start_mitid(\n  vendor_data: \"your-customer-reference\",\n  metadata: { reference: \"example\" },\n  country: \"DNK\",\n  return_url: \"https://app.example.com/identity/complete\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.IdWallets.StartMitidAsync(new DigitalIdWalletApiMitidWalletVerificationStartRequest\n{\n    VendorData = \"your-customer-reference\",\n    Metadata = new Dictionary<string, object> { [\"reference\"] = \"example\" },\n    Country = new DigitalIdWalletApiMitidWalletVerificationStartCountryEnum(\"DNK\"),\n    ReturnUrl = \"https://app.example.com/identity/complete\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "x-didit-wallet-id": "mitid"
      }
    },
    "/v3/id-verification/wallets/bankid-se/": {
      "post": {
        "operationId": "start_bankid_se_wallet_verification",
        "x-didit-sdk": {
          "resource": "id_wallets",
          "method": "start_bankid_se",
          "auth": "api_key",
          "server": true
        },
        "description": "Mulai proses masuk BankID (SWE) (Finansiell ID-Teknik / konsorsium bank; SWE) tanpa alur kerja apa pun. Ditagih sekali, hanya ketika identitas terverifikasi. Respons membawa next_action.type=redirect beserta URL untuk mengarahkan browser pengguna; pengguna kembali ke return_url dengan request_id dan result yang dilampirkan. Baca hasilnya dengan GET /v3/id-verification/wallets/verifications/{request_id}/ atau dari webhook, jangan pernah dari URL. Aplikasi sandbox mendapatkan simulasi deterministik (simulated: true) yang tidak pernah menghubungi penyedia.",
        "summary": "Mulai verifikasi BankID (SWE)",
        "parameters": [
          {
            "in": "header",
            "name": "Idempotency-Key",
            "schema": {
              "type": "string"
            },
            "description": "Kunci keamanan coba lagi opsional (maks 255 karakter). Mencoba lagi dengan kunci, dompet, dan body yang sama akan mengembalikan verifikasi asli tanpa memulai proses masuk kedua; kunci yang sama dengan dompet atau body lain akan mengembalikan 409 idempotency_key_reused."
          }
        ],
        "tags": [
          "Digital ID wallets"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiBankidSeWalletVerificationStartRequest"
              },
              "example": {
                "country": "SWE",
                "vendor_data": "your-customer-reference",
                "metadata": {
                  "reference": "example"
                },
                "return_url": "https://app.example.com/identity/complete"
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiBankidSeWalletVerificationStartRequest"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiBankidSeWalletVerificationStartRequest"
              }
            }
          },
          "required": true
        },
        "security": [
          {
            "ApiKeyAuth": []
          },
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationResponse"
                },
                "example": {
                  "request_id": "00000000-0000-4000-8000-000000000001",
                  "wallet_verification": {
                    "wallet": {
                      "id": "bankid_se",
                      "name": "BankID",
                      "issuing_authority": "Finansiell ID-Teknik / bank consortium"
                    },
                    "country": "SWE",
                    "status": "Not Finished",
                    "outcome": "pending",
                    "error": null,
                    "interaction": "redirect",
                    "simulated": false,
                    "expires_at": "2026-01-01T10:10:00Z",
                    "next_action": {
                      "type": "redirect",
                      "url": "https://wallet.example.com/authorize"
                    },
                    "identity": null,
                    "attributes": null,
                    "level_of_assurance": null,
                    "verified_at": null,
                    "signature_valid": null,
                    "credential_type": "person_identification"
                  },
                  "vendor_data": "your-customer-reference",
                  "metadata": {
                    "reference": "example"
                  },
                  "created_at": "2026-01-01T10:00:00Z"
                }
              }
            },
            "description": ""
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationStartBadRequest"
                }
              }
            },
            "description": "Error validasi kolom ({field: [messages]}), atau error return_url_invalid, return_url_not_allowed, invalid_personal_code, invalid_phone_number, atau idempotency_key_invalid."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationStartForbidden"
                }
              }
            },
            "description": "Kredensial tidak ada ({detail}), atau kesalahan wallet_unavailable, insufficient_credits, atau contract_rate_missing."
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "kesalahan idempotency_key_reused atau idempotency_key_in_progress (dengan Retry-After)."
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "kesalahan wallet_provider_unavailable: penyedia tidak dapat memulai; tidak ada yang dibuat."
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "kesalahan wallet_not_configured: lingkungan ini tidak dapat menjangkau dompet."
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL",
            "source": "curl --request POST \\\n  --url https://verification.didit.me/v3/id-verification/wallets/bankid-se/ \\\n  --header 'x-api-key: YOUR_API_KEY' \\\n  --header 'Idempotency-Key: your-unique-attempt-key' \\\n  --header 'Content-Type: application/json' \\\n  --data '{\n  \"country\": \"SWE\",\n  \"vendor_data\": \"your-customer-reference\",\n  \"metadata\": {\n    \"reference\": \"example\"\n  },\n  \"return_url\": \"https://app.example.com/identity/complete\"\n}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.id_wallets.start_bankid_se(\n    vendor_data=\"your-customer-reference\",\n    metadata={\"reference\": \"example\"},\n    country=\"SWE\",\n    return_url=\"https://app.example.com/identity/complete\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.idWallets.startBankidSe({\n  vendor_data: \"your-customer-reference\",\n  metadata: { reference: \"example\" },\n  country: \"SWE\",\n  return_url: \"https://app.example.com/identity/complete\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.IDWallets.StartBankidSe(ctx, didit.IDWalletsStartBankidSeParams{\n\tBody: didit.DigitalIDWalletAPIBankidSeWalletVerificationStartRequest{\n\t\tVendorData: didit.String(\"your-customer-reference\"),\n\t\tMetadata:   didit.Some(map[string]any{\"reference\": \"example\"}),\n\t\tCountry:    didit.Some(didit.DigitalIDWalletAPICountryEe9enum(\"SWE\")),\n\t\tReturnURL:  \"https://app.example.com/identity/complete\",\n\t},\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.DigitalIdWalletApiBankidSeWalletVerificationStartRequest;\nimport me.didit.types.DigitalIdWalletApiCountryEe9Enum;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.idWallets().startBankidSe(DigitalIdWalletApiBankidSeWalletVerificationStartRequest.builder()\n        .vendorData(\"your-customer-reference\")\n        .metadata(Map.of(\"reference\", \"example\"))\n        .country(DigitalIdWalletApiCountryEe9Enum.of(\"SWE\"))\n        .returnUrl(\"https://app.example.com/identity/complete\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->idWallets->startBankidSe([\n    'vendor_data' => 'your-customer-reference',\n    'metadata' => ['reference' => 'example'],\n    'country' => 'SWE',\n    'return_url' => 'https://app.example.com/identity/complete',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.id_wallets.start_bankid_se(\n  vendor_data: \"your-customer-reference\",\n  metadata: { reference: \"example\" },\n  country: \"SWE\",\n  return_url: \"https://app.example.com/identity/complete\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.IdWallets.StartBankidSeAsync(new DigitalIdWalletApiBankidSeWalletVerificationStartRequest\n{\n    VendorData = \"your-customer-reference\",\n    Metadata = new Dictionary<string, object> { [\"reference\"] = \"example\" },\n    Country = new DigitalIdWalletApiCountryEe9Enum(\"SWE\"),\n    ReturnUrl = \"https://app.example.com/identity/complete\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "x-didit-wallet-id": "bankid_se"
      }
    },
    "/v3/id-verification/wallets/bankid-no/": {
      "post": {
        "operationId": "start_bankid_no_wallet_verification",
        "x-didit-sdk": {
          "resource": "id_wallets",
          "method": "start_bankid_no",
          "auth": "api_key",
          "server": true
        },
        "description": "Mulai proses masuk BankID (NOR) (BankID BankAxept AS; NOR) tanpa alur kerja apa pun. Ditagih sekali, hanya ketika identitas terverifikasi. Respons membawa next_action.type=redirect beserta URL untuk mengarahkan browser pengguna; pengguna kembali ke return_url dengan request_id dan result yang dilampirkan. Baca hasilnya dengan GET /v3/id-verification/wallets/verifications/{request_id}/ atau dari webhook, jangan pernah dari URL. Aplikasi sandbox mendapatkan simulasi deterministik (simulated: true) yang tidak pernah menghubungi penyedia.",
        "summary": "Mulai verifikasi BankID (NOR)",
        "parameters": [
          {
            "in": "header",
            "name": "Idempotency-Key",
            "schema": {
              "type": "string"
            },
            "description": "Kunci keamanan coba lagi opsional (maks 255 karakter). Mencoba lagi dengan kunci, dompet, dan body yang sama akan mengembalikan verifikasi asli tanpa memulai proses masuk kedua; kunci yang sama dengan dompet atau body lain akan mengembalikan 409 idempotency_key_reused."
          }
        ],
        "tags": [
          "Digital ID wallets"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiBankidNoWalletVerificationStartRequest"
              },
              "example": {
                "country": "NOR",
                "vendor_data": "your-customer-reference",
                "metadata": {
                  "reference": "example"
                },
                "return_url": "https://app.example.com/identity/complete"
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiBankidNoWalletVerificationStartRequest"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiBankidNoWalletVerificationStartRequest"
              }
            }
          },
          "required": true
        },
        "security": [
          {
            "ApiKeyAuth": []
          },
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationResponse"
                },
                "example": {
                  "request_id": "00000000-0000-4000-8000-000000000001",
                  "wallet_verification": {
                    "wallet": {
                      "id": "bankid_no",
                      "name": "BankID",
                      "issuing_authority": "BankID BankAxept AS"
                    },
                    "country": "NOR",
                    "status": "Not Finished",
                    "outcome": "pending",
                    "error": null,
                    "interaction": "redirect",
                    "simulated": false,
                    "expires_at": "2026-01-01T10:10:00Z",
                    "next_action": {
                      "type": "redirect",
                      "url": "https://wallet.example.com/authorize"
                    },
                    "identity": null,
                    "attributes": null,
                    "level_of_assurance": null,
                    "verified_at": null,
                    "signature_valid": null,
                    "credential_type": "person_identification"
                  },
                  "vendor_data": "your-customer-reference",
                  "metadata": {
                    "reference": "example"
                  },
                  "created_at": "2026-01-01T10:00:00Z"
                }
              }
            },
            "description": ""
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationStartBadRequest"
                }
              }
            },
            "description": "Error validasi kolom ({field: [messages]}), atau error return_url_invalid, return_url_not_allowed, invalid_personal_code, invalid_phone_number, atau idempotency_key_invalid."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationStartForbidden"
                }
              }
            },
            "description": "Kredensial tidak ada ({detail}), atau kesalahan wallet_unavailable, insufficient_credits, atau contract_rate_missing."
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "kesalahan idempotency_key_reused atau idempotency_key_in_progress (dengan Retry-After)."
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "kesalahan wallet_provider_unavailable: penyedia tidak dapat memulai; tidak ada yang dibuat."
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "kesalahan wallet_not_configured: lingkungan ini tidak dapat menjangkau dompet."
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL",
            "source": "curl --request POST \\\n  --url https://verification.didit.me/v3/id-verification/wallets/bankid-no/ \\\n  --header 'x-api-key: YOUR_API_KEY' \\\n  --header 'Idempotency-Key: your-unique-attempt-key' \\\n  --header 'Content-Type: application/json' \\\n  --data '{\n  \"country\": \"NOR\",\n  \"vendor_data\": \"your-customer-reference\",\n  \"metadata\": {\n    \"reference\": \"example\"\n  },\n  \"return_url\": \"https://app.example.com/identity/complete\"\n}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.id_wallets.start_bankid_no(\n    vendor_data=\"your-customer-reference\",\n    metadata={\"reference\": \"example\"},\n    country=\"NOR\",\n    return_url=\"https://app.example.com/identity/complete\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.idWallets.startBankidNo({\n  vendor_data: \"your-customer-reference\",\n  metadata: { reference: \"example\" },\n  country: \"NOR\",\n  return_url: \"https://app.example.com/identity/complete\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.IDWallets.StartBankidNo(ctx, didit.IDWalletsStartBankidNoParams{\n\tBody: didit.DigitalIDWalletAPIBankidNoWalletVerificationStartRequest{\n\t\tVendorData: didit.String(\"your-customer-reference\"),\n\t\tMetadata:   didit.Some(map[string]any{\"reference\": \"example\"}),\n\t\tCountry:    didit.Some(didit.DigitalIDWalletAPICountryAfcEnum(\"NOR\")),\n\t\tReturnURL:  \"https://app.example.com/identity/complete\",\n\t},\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.DigitalIdWalletApiBankidNoWalletVerificationStartRequest;\nimport me.didit.types.DigitalIdWalletApiCountryAfcEnum;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.idWallets().startBankidNo(DigitalIdWalletApiBankidNoWalletVerificationStartRequest.builder()\n        .vendorData(\"your-customer-reference\")\n        .metadata(Map.of(\"reference\", \"example\"))\n        .country(DigitalIdWalletApiCountryAfcEnum.of(\"NOR\"))\n        .returnUrl(\"https://app.example.com/identity/complete\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->idWallets->startBankidNo([\n    'vendor_data' => 'your-customer-reference',\n    'metadata' => ['reference' => 'example'],\n    'country' => 'NOR',\n    'return_url' => 'https://app.example.com/identity/complete',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.id_wallets.start_bankid_no(\n  vendor_data: \"your-customer-reference\",\n  metadata: { reference: \"example\" },\n  country: \"NOR\",\n  return_url: \"https://app.example.com/identity/complete\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.IdWallets.StartBankidNoAsync(new DigitalIdWalletApiBankidNoWalletVerificationStartRequest\n{\n    VendorData = \"your-customer-reference\",\n    Metadata = new Dictionary<string, object> { [\"reference\"] = \"example\" },\n    Country = new DigitalIdWalletApiCountryAfcEnum(\"NOR\"),\n    ReturnUrl = \"https://app.example.com/identity/complete\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "x-didit-wallet-id": "bankid_no"
      }
    },
    "/v3/id-verification/wallets/vipps/": {
      "post": {
        "operationId": "start_vipps_wallet_verification",
        "x-didit-sdk": {
          "resource": "id_wallets",
          "method": "start_vipps",
          "auth": "api_key",
          "server": true
        },
        "description": "Mulai proses masuk Vipps (Vipps MobilePay / BankID NO; NOR) tanpa alur kerja apa pun. Ditagih sekali, hanya saat identitas terverifikasi. Respons membawa next_action.type=redirect berisi URL tujuan pengalihan browser pengguna; pengguna kembali ke return_url dengan request_id dan result yang ditambahkan. Baca hasilnya dengan GET /v3/id-verification/wallets/verifications/{request_id}/ atau dari webhook, jangan pernah dari URL. Aplikasi sandbox mendapatkan simulasi deterministik (simulated: true) yang tidak pernah menghubungi penyedia.",
        "summary": "Mulai verifikasi Vipps",
        "parameters": [
          {
            "in": "header",
            "name": "Idempotency-Key",
            "schema": {
              "type": "string"
            },
            "description": "Kunci keamanan coba lagi opsional (maks 255 karakter). Mencoba lagi dengan kunci, dompet, dan body yang sama akan mengembalikan verifikasi asli tanpa memulai proses masuk kedua; kunci yang sama dengan dompet atau body lain akan mengembalikan 409 idempotency_key_reused."
          }
        ],
        "tags": [
          "Digital ID wallets"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiVippsWalletVerificationStartRequest"
              },
              "example": {
                "country": "NOR",
                "vendor_data": "your-customer-reference",
                "metadata": {
                  "reference": "example"
                },
                "return_url": "https://app.example.com/identity/complete"
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiVippsWalletVerificationStartRequest"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiVippsWalletVerificationStartRequest"
              }
            }
          },
          "required": true
        },
        "security": [
          {
            "ApiKeyAuth": []
          },
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationResponse"
                },
                "example": {
                  "request_id": "00000000-0000-4000-8000-000000000001",
                  "wallet_verification": {
                    "wallet": {
                      "id": "vipps",
                      "name": "Vipps",
                      "issuing_authority": "Vipps MobilePay / BankID NO"
                    },
                    "country": "NOR",
                    "status": "Not Finished",
                    "outcome": "pending",
                    "error": null,
                    "interaction": "redirect",
                    "simulated": false,
                    "expires_at": "2026-01-01T10:10:00Z",
                    "next_action": {
                      "type": "redirect",
                      "url": "https://wallet.example.com/authorize"
                    },
                    "identity": null,
                    "attributes": null,
                    "level_of_assurance": null,
                    "verified_at": null,
                    "signature_valid": null,
                    "credential_type": "person_identification"
                  },
                  "vendor_data": "your-customer-reference",
                  "metadata": {
                    "reference": "example"
                  },
                  "created_at": "2026-01-01T10:00:00Z"
                }
              }
            },
            "description": ""
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationStartBadRequest"
                }
              }
            },
            "description": "Error validasi kolom ({field: [messages]}), atau error return_url_invalid, return_url_not_allowed, invalid_personal_code, invalid_phone_number, atau idempotency_key_invalid."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationStartForbidden"
                }
              }
            },
            "description": "Kredensial tidak ada ({detail}), atau kesalahan wallet_unavailable, insufficient_credits, atau contract_rate_missing."
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "kesalahan idempotency_key_reused atau idempotency_key_in_progress (dengan Retry-After)."
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "kesalahan wallet_provider_unavailable: penyedia tidak dapat memulai; tidak ada yang dibuat."
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "kesalahan wallet_not_configured: lingkungan ini tidak dapat menjangkau dompet."
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL",
            "source": "curl --request POST \\\n  --url https://verification.didit.me/v3/id-verification/wallets/vipps/ \\\n  --header 'x-api-key: YOUR_API_KEY' \\\n  --header 'Idempotency-Key: your-unique-attempt-key' \\\n  --header 'Content-Type: application/json' \\\n  --data '{\n  \"country\": \"NOR\",\n  \"vendor_data\": \"your-customer-reference\",\n  \"metadata\": {\n    \"reference\": \"example\"\n  },\n  \"return_url\": \"https://app.example.com/identity/complete\"\n}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.id_wallets.start_vipps(\n    vendor_data=\"your-customer-reference\",\n    metadata={\"reference\": \"example\"},\n    country=\"NOR\",\n    return_url=\"https://app.example.com/identity/complete\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.idWallets.startVipps({\n  vendor_data: \"your-customer-reference\",\n  metadata: { reference: \"example\" },\n  country: \"NOR\",\n  return_url: \"https://app.example.com/identity/complete\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.IDWallets.StartVipps(ctx, didit.IDWalletsStartVippsParams{\n\tBody: didit.DigitalIDWalletAPIVippsWalletVerificationStartRequest{\n\t\tVendorData: didit.String(\"your-customer-reference\"),\n\t\tMetadata:   didit.Some(map[string]any{\"reference\": \"example\"}),\n\t\tCountry:    didit.Some(didit.DigitalIDWalletAPICountryAfcEnum(\"NOR\")),\n\t\tReturnURL:  \"https://app.example.com/identity/complete\",\n\t},\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.DigitalIdWalletApiCountryAfcEnum;\nimport me.didit.types.DigitalIdWalletApiVippsWalletVerificationStartRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.idWallets().startVipps(DigitalIdWalletApiVippsWalletVerificationStartRequest.builder()\n        .vendorData(\"your-customer-reference\")\n        .metadata(Map.of(\"reference\", \"example\"))\n        .country(DigitalIdWalletApiCountryAfcEnum.of(\"NOR\"))\n        .returnUrl(\"https://app.example.com/identity/complete\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->idWallets->startVipps([\n    'vendor_data' => 'your-customer-reference',\n    'metadata' => ['reference' => 'example'],\n    'country' => 'NOR',\n    'return_url' => 'https://app.example.com/identity/complete',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.id_wallets.start_vipps(\n  vendor_data: \"your-customer-reference\",\n  metadata: { reference: \"example\" },\n  country: \"NOR\",\n  return_url: \"https://app.example.com/identity/complete\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.IdWallets.StartVippsAsync(new DigitalIdWalletApiVippsWalletVerificationStartRequest\n{\n    VendorData = \"your-customer-reference\",\n    Metadata = new Dictionary<string, object> { [\"reference\"] = \"example\" },\n    Country = new DigitalIdWalletApiCountryAfcEnum(\"NOR\"),\n    ReturnUrl = \"https://app.example.com/identity/complete\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "x-didit-wallet-id": "vipps"
      }
    },
    "/v3/id-verification/wallets/buypass/": {
      "post": {
        "operationId": "start_buypass_wallet_verification",
        "x-didit-sdk": {
          "resource": "id_wallets",
          "method": "start_buypass",
          "auth": "api_key",
          "server": true
        },
        "description": "Mulai proses masuk Buypass ID (Buypass AS; NOR) tanpa alur kerja apa pun. Ditagih sekali, hanya ketika identitas terverifikasi. Respons membawa next_action.type=redirect beserta URL untuk mengarahkan browser pengguna; pengguna kembali ke return_url dengan request_id dan result yang dilampirkan. Baca hasilnya dengan GET /v3/id-verification/wallets/verifications/{request_id}/ atau dari webhook, jangan pernah dari URL. Aplikasi sandbox mendapatkan simulasi deterministik (simulated: true) yang tidak pernah menghubungi penyedia.",
        "summary": "Mulai verifikasi Buypass ID",
        "parameters": [
          {
            "in": "header",
            "name": "Idempotency-Key",
            "schema": {
              "type": "string"
            },
            "description": "Kunci keamanan coba lagi opsional (maks 255 karakter). Mencoba lagi dengan kunci, dompet, dan body yang sama akan mengembalikan verifikasi asli tanpa memulai proses masuk kedua; kunci yang sama dengan dompet atau body lain akan mengembalikan 409 idempotency_key_reused."
          }
        ],
        "tags": [
          "Digital ID wallets"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiBuypassWalletVerificationStartRequest"
              },
              "example": {
                "country": "NOR",
                "vendor_data": "your-customer-reference",
                "metadata": {
                  "reference": "example"
                },
                "return_url": "https://app.example.com/identity/complete"
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiBuypassWalletVerificationStartRequest"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiBuypassWalletVerificationStartRequest"
              }
            }
          },
          "required": true
        },
        "security": [
          {
            "ApiKeyAuth": []
          },
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationResponse"
                },
                "example": {
                  "request_id": "00000000-0000-4000-8000-000000000001",
                  "wallet_verification": {
                    "wallet": {
                      "id": "buypass",
                      "name": "Buypass ID",
                      "issuing_authority": "Buypass AS"
                    },
                    "country": "NOR",
                    "status": "Not Finished",
                    "outcome": "pending",
                    "error": null,
                    "interaction": "redirect",
                    "simulated": false,
                    "expires_at": "2026-01-01T10:10:00Z",
                    "next_action": {
                      "type": "redirect",
                      "url": "https://wallet.example.com/authorize"
                    },
                    "identity": null,
                    "attributes": null,
                    "level_of_assurance": null,
                    "verified_at": null,
                    "signature_valid": null,
                    "credential_type": "person_identification"
                  },
                  "vendor_data": "your-customer-reference",
                  "metadata": {
                    "reference": "example"
                  },
                  "created_at": "2026-01-01T10:00:00Z"
                }
              }
            },
            "description": ""
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationStartBadRequest"
                }
              }
            },
            "description": "Error validasi kolom ({field: [messages]}), atau error return_url_invalid, return_url_not_allowed, invalid_personal_code, invalid_phone_number, atau idempotency_key_invalid."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationStartForbidden"
                }
              }
            },
            "description": "Kredensial tidak ada ({detail}), atau kesalahan wallet_unavailable, insufficient_credits, atau contract_rate_missing."
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "kesalahan idempotency_key_reused atau idempotency_key_in_progress (dengan Retry-After)."
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "kesalahan wallet_provider_unavailable: penyedia tidak dapat memulai; tidak ada yang dibuat."
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "kesalahan wallet_not_configured: lingkungan ini tidak dapat menjangkau dompet."
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL",
            "source": "curl --request POST \\\n  --url https://verification.didit.me/v3/id-verification/wallets/buypass/ \\\n  --header 'x-api-key: YOUR_API_KEY' \\\n  --header 'Idempotency-Key: your-unique-attempt-key' \\\n  --header 'Content-Type: application/json' \\\n  --data '{\n  \"country\": \"NOR\",\n  \"vendor_data\": \"your-customer-reference\",\n  \"metadata\": {\n    \"reference\": \"example\"\n  },\n  \"return_url\": \"https://app.example.com/identity/complete\"\n}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.id_wallets.start_buypass(\n    vendor_data=\"your-customer-reference\",\n    metadata={\"reference\": \"example\"},\n    country=\"NOR\",\n    return_url=\"https://app.example.com/identity/complete\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.idWallets.startBuypass({\n  vendor_data: \"your-customer-reference\",\n  metadata: { reference: \"example\" },\n  country: \"NOR\",\n  return_url: \"https://app.example.com/identity/complete\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.IDWallets.StartBuypass(ctx, didit.IDWalletsStartBuypassParams{\n\tBody: didit.DigitalIDWalletAPIBuypassWalletVerificationStartRequest{\n\t\tVendorData: didit.String(\"your-customer-reference\"),\n\t\tMetadata:   didit.Some(map[string]any{\"reference\": \"example\"}),\n\t\tCountry:    didit.Some(didit.DigitalIDWalletAPICountryAfcEnum(\"NOR\")),\n\t\tReturnURL:  \"https://app.example.com/identity/complete\",\n\t},\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.DigitalIdWalletApiBuypassWalletVerificationStartRequest;\nimport me.didit.types.DigitalIdWalletApiCountryAfcEnum;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.idWallets().startBuypass(DigitalIdWalletApiBuypassWalletVerificationStartRequest.builder()\n        .vendorData(\"your-customer-reference\")\n        .metadata(Map.of(\"reference\", \"example\"))\n        .country(DigitalIdWalletApiCountryAfcEnum.of(\"NOR\"))\n        .returnUrl(\"https://app.example.com/identity/complete\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->idWallets->startBuypass([\n    'vendor_data' => 'your-customer-reference',\n    'metadata' => ['reference' => 'example'],\n    'country' => 'NOR',\n    'return_url' => 'https://app.example.com/identity/complete',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.id_wallets.start_buypass(\n  vendor_data: \"your-customer-reference\",\n  metadata: { reference: \"example\" },\n  country: \"NOR\",\n  return_url: \"https://app.example.com/identity/complete\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.IdWallets.StartBuypassAsync(new DigitalIdWalletApiBuypassWalletVerificationStartRequest\n{\n    VendorData = \"your-customer-reference\",\n    Metadata = new Dictionary<string, object> { [\"reference\"] = \"example\" },\n    Country = new DigitalIdWalletApiCountryAfcEnum(\"NOR\"),\n    ReturnUrl = \"https://app.example.com/identity/complete\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "x-didit-wallet-id": "buypass"
      }
    },
    "/v3/id-verification/wallets/itsme/": {
      "post": {
        "operationId": "start_itsme_wallet_verification",
        "x-didit-sdk": {
          "resource": "id_wallets",
          "method": "start_itsme",
          "auth": "api_key",
          "server": true
        },
        "description": "Mulai proses masuk itsme (Belgian Mobile ID; BEL, LUX, NLD) tanpa alur kerja apa pun. Ditagih satu kali, hanya ketika identitas terverifikasi. Respons membawa next_action.type=redirect dengan URL tujuan browser pengguna; pengguna kembali ke return_url dengan request_id dan result yang dilampirkan. Baca hasilnya dengan GET /v3/id-verification/wallets/verifications/{request_id}/ atau dari webhook, jangan pernah dari URL. Aplikasi sandbox mendapatkan simulasi deterministik (simulated: true) yang tidak pernah menghubungi penyedia.",
        "summary": "Mulai verifikasi itsme",
        "parameters": [
          {
            "in": "header",
            "name": "Idempotency-Key",
            "schema": {
              "type": "string"
            },
            "description": "Kunci keamanan coba lagi opsional (maks 255 karakter). Mencoba lagi dengan kunci, dompet, dan body yang sama akan mengembalikan verifikasi asli tanpa memulai proses masuk kedua; kunci yang sama dengan dompet atau body lain akan mengembalikan 409 idempotency_key_reused."
          }
        ],
        "tags": [
          "Digital ID wallets"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiItsmeWalletVerificationStartRequest"
              },
              "example": {
                "country": "BEL",
                "vendor_data": "your-customer-reference",
                "metadata": {
                  "reference": "example"
                },
                "return_url": "https://app.example.com/identity/complete"
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiItsmeWalletVerificationStartRequest"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiItsmeWalletVerificationStartRequest"
              }
            }
          },
          "required": true
        },
        "security": [
          {
            "ApiKeyAuth": []
          },
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationResponse"
                },
                "example": {
                  "request_id": "00000000-0000-4000-8000-000000000001",
                  "wallet_verification": {
                    "wallet": {
                      "id": "itsme",
                      "name": "itsme",
                      "issuing_authority": "Belgian Mobile ID"
                    },
                    "country": "BEL",
                    "status": "Not Finished",
                    "outcome": "pending",
                    "error": null,
                    "interaction": "redirect",
                    "simulated": false,
                    "expires_at": "2026-01-01T10:10:00Z",
                    "next_action": {
                      "type": "redirect",
                      "url": "https://wallet.example.com/authorize"
                    },
                    "identity": null,
                    "attributes": null,
                    "level_of_assurance": null,
                    "verified_at": null,
                    "signature_valid": null,
                    "credential_type": "person_identification"
                  },
                  "vendor_data": "your-customer-reference",
                  "metadata": {
                    "reference": "example"
                  },
                  "created_at": "2026-01-01T10:00:00Z"
                }
              }
            },
            "description": ""
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationStartBadRequest"
                }
              }
            },
            "description": "Error validasi kolom ({field: [messages]}), atau error return_url_invalid, return_url_not_allowed, invalid_personal_code, invalid_phone_number, atau idempotency_key_invalid."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationStartForbidden"
                }
              }
            },
            "description": "Kredensial tidak ada ({detail}), atau kesalahan wallet_unavailable, insufficient_credits, atau contract_rate_missing."
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "kesalahan idempotency_key_reused atau idempotency_key_in_progress (dengan Retry-After)."
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "kesalahan wallet_provider_unavailable: penyedia tidak dapat memulai; tidak ada yang dibuat."
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "kesalahan wallet_not_configured: lingkungan ini tidak dapat menjangkau dompet."
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL",
            "source": "curl --request POST \\\n  --url https://verification.didit.me/v3/id-verification/wallets/itsme/ \\\n  --header 'x-api-key: YOUR_API_KEY' \\\n  --header 'Idempotency-Key: your-unique-attempt-key' \\\n  --header 'Content-Type: application/json' \\\n  --data '{\n  \"country\": \"BEL\",\n  \"vendor_data\": \"your-customer-reference\",\n  \"metadata\": {\n    \"reference\": \"example\"\n  },\n  \"return_url\": \"https://app.example.com/identity/complete\"\n}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.id_wallets.start_itsme(\n    vendor_data=\"your-customer-reference\",\n    metadata={\"reference\": \"example\"},\n    country=\"BEL\",\n    return_url=\"https://app.example.com/identity/complete\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.idWallets.startItsme({\n  vendor_data: \"your-customer-reference\",\n  metadata: { reference: \"example\" },\n  country: \"BEL\",\n  return_url: \"https://app.example.com/identity/complete\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.IDWallets.StartItsme(ctx, didit.IDWalletsStartItsmeParams{\n\tBody: didit.DigitalIDWalletAPIItsmeWalletVerificationStartRequest{\n\t\tVendorData: didit.String(\"your-customer-reference\"),\n\t\tMetadata:   didit.Some(map[string]any{\"reference\": \"example\"}),\n\t\tCountry:    didit.DigitalIDWalletAPIItsmeWalletVerificationStartCountryEnum(\"BEL\"),\n\t\tReturnURL:  \"https://app.example.com/identity/complete\",\n\t},\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.DigitalIdWalletApiItsmeWalletVerificationStartCountryEnum;\nimport me.didit.types.DigitalIdWalletApiItsmeWalletVerificationStartRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.idWallets().startItsme(DigitalIdWalletApiItsmeWalletVerificationStartRequest.builder()\n        .vendorData(\"your-customer-reference\")\n        .metadata(Map.of(\"reference\", \"example\"))\n        .country(DigitalIdWalletApiItsmeWalletVerificationStartCountryEnum.of(\"BEL\"))\n        .returnUrl(\"https://app.example.com/identity/complete\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->idWallets->startItsme([\n    'vendor_data' => 'your-customer-reference',\n    'metadata' => ['reference' => 'example'],\n    'country' => 'BEL',\n    'return_url' => 'https://app.example.com/identity/complete',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.id_wallets.start_itsme(\n  vendor_data: \"your-customer-reference\",\n  metadata: { reference: \"example\" },\n  country: \"BEL\",\n  return_url: \"https://app.example.com/identity/complete\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.IdWallets.StartItsmeAsync(new DigitalIdWalletApiItsmeWalletVerificationStartRequest\n{\n    VendorData = \"your-customer-reference\",\n    Metadata = new Dictionary<string, object> { [\"reference\"] = \"example\" },\n    Country = \"BEL\",\n    ReturnUrl = \"https://app.example.com/identity/complete\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "x-didit-wallet-id": "itsme"
      }
    },
    "/v3/id-verification/wallets/idin/": {
      "post": {
        "operationId": "start_idin_wallet_verification",
        "x-didit-sdk": {
          "resource": "id_wallets",
          "method": "start_idin",
          "auth": "api_key",
          "server": true
        },
        "description": "Mulai proses masuk iDIN (bank-bank Belanda (Currence iDIN); NLD) tanpa alur kerja apa pun. Ditagih satu kali, hanya ketika identitas terverifikasi. Respons membawa next_action.type=redirect dengan URL tujuan browser pengguna; pengguna kembali ke return_url dengan request_id dan result yang dilampirkan. Baca hasilnya dengan GET /v3/id-verification/wallets/verifications/{request_id}/ atau dari webhook, jangan pernah dari URL. Aplikasi sandbox mendapatkan simulasi deterministik (simulated: true) yang tidak pernah menghubungi penyedia.",
        "summary": "Mulai verifikasi iDIN",
        "parameters": [
          {
            "in": "header",
            "name": "Idempotency-Key",
            "schema": {
              "type": "string"
            },
            "description": "Kunci keamanan coba lagi opsional (maks 255 karakter). Mencoba lagi dengan kunci, dompet, dan body yang sama akan mengembalikan verifikasi asli tanpa memulai proses masuk kedua; kunci yang sama dengan dompet atau body lain akan mengembalikan 409 idempotency_key_reused."
          }
        ],
        "tags": [
          "Digital ID wallets"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiIdinWalletVerificationStartRequest"
              },
              "example": {
                "country": "NLD",
                "vendor_data": "your-customer-reference",
                "metadata": {
                  "reference": "example"
                },
                "return_url": "https://app.example.com/identity/complete"
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiIdinWalletVerificationStartRequest"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiIdinWalletVerificationStartRequest"
              }
            }
          },
          "required": true
        },
        "security": [
          {
            "ApiKeyAuth": []
          },
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationResponse"
                },
                "example": {
                  "request_id": "00000000-0000-4000-8000-000000000001",
                  "wallet_verification": {
                    "wallet": {
                      "id": "idin",
                      "name": "iDIN",
                      "issuing_authority": "Dutch banks (Currence iDIN)"
                    },
                    "country": "NLD",
                    "status": "Not Finished",
                    "outcome": "pending",
                    "error": null,
                    "interaction": "redirect",
                    "simulated": false,
                    "expires_at": "2026-01-01T10:10:00Z",
                    "next_action": {
                      "type": "redirect",
                      "url": "https://wallet.example.com/authorize"
                    },
                    "identity": null,
                    "attributes": null,
                    "level_of_assurance": null,
                    "verified_at": null,
                    "signature_valid": null,
                    "credential_type": "person_identification"
                  },
                  "vendor_data": "your-customer-reference",
                  "metadata": {
                    "reference": "example"
                  },
                  "created_at": "2026-01-01T10:00:00Z"
                }
              }
            },
            "description": ""
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationStartBadRequest"
                }
              }
            },
            "description": "Error validasi kolom ({field: [messages]}), atau error return_url_invalid, return_url_not_allowed, invalid_personal_code, invalid_phone_number, atau idempotency_key_invalid."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationStartForbidden"
                }
              }
            },
            "description": "Kredensial tidak ada ({detail}), atau kesalahan wallet_unavailable, insufficient_credits, atau contract_rate_missing."
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "kesalahan idempotency_key_reused atau idempotency_key_in_progress (dengan Retry-After)."
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "kesalahan wallet_provider_unavailable: penyedia tidak dapat memulai; tidak ada yang dibuat."
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "kesalahan wallet_not_configured: lingkungan ini tidak dapat menjangkau dompet."
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL",
            "source": "curl --request POST \\\n  --url https://verification.didit.me/v3/id-verification/wallets/idin/ \\\n  --header 'x-api-key: YOUR_API_KEY' \\\n  --header 'Idempotency-Key: your-unique-attempt-key' \\\n  --header 'Content-Type: application/json' \\\n  --data '{\n  \"country\": \"NLD\",\n  \"vendor_data\": \"your-customer-reference\",\n  \"metadata\": {\n    \"reference\": \"example\"\n  },\n  \"return_url\": \"https://app.example.com/identity/complete\"\n}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.id_wallets.start_idin(\n    vendor_data=\"your-customer-reference\",\n    metadata={\"reference\": \"example\"},\n    country=\"NLD\",\n    return_url=\"https://app.example.com/identity/complete\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.idWallets.startIdin({\n  vendor_data: \"your-customer-reference\",\n  metadata: { reference: \"example\" },\n  country: \"NLD\",\n  return_url: \"https://app.example.com/identity/complete\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.IDWallets.StartIdin(ctx, didit.IDWalletsStartIdinParams{\n\tBody: didit.DigitalIDWalletAPIIdinWalletVerificationStartRequest{\n\t\tVendorData: didit.String(\"your-customer-reference\"),\n\t\tMetadata:   didit.Some(map[string]any{\"reference\": \"example\"}),\n\t\tCountry:    didit.Some(didit.DigitalIDWalletAPIIdinWalletVerificationStartCountryEnum(\"NLD\")),\n\t\tReturnURL:  \"https://app.example.com/identity/complete\",\n\t},\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.DigitalIdWalletApiIdinWalletVerificationStartCountryEnum;\nimport me.didit.types.DigitalIdWalletApiIdinWalletVerificationStartRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.idWallets().startIdin(DigitalIdWalletApiIdinWalletVerificationStartRequest.builder()\n        .vendorData(\"your-customer-reference\")\n        .metadata(Map.of(\"reference\", \"example\"))\n        .country(DigitalIdWalletApiIdinWalletVerificationStartCountryEnum.of(\"NLD\"))\n        .returnUrl(\"https://app.example.com/identity/complete\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->idWallets->startIdin([\n    'vendor_data' => 'your-customer-reference',\n    'metadata' => ['reference' => 'example'],\n    'country' => 'NLD',\n    'return_url' => 'https://app.example.com/identity/complete',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.id_wallets.start_idin(\n  vendor_data: \"your-customer-reference\",\n  metadata: { reference: \"example\" },\n  country: \"NLD\",\n  return_url: \"https://app.example.com/identity/complete\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.IdWallets.StartIdinAsync(new DigitalIdWalletApiIdinWalletVerificationStartRequest\n{\n    VendorData = \"your-customer-reference\",\n    Metadata = new Dictionary<string, object> { [\"reference\"] = \"example\" },\n    Country = new DigitalIdWalletApiIdinWalletVerificationStartCountryEnum(\"NLD\"),\n    ReturnUrl = \"https://app.example.com/identity/complete\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "x-didit-wallet-id": "idin"
      }
    },
    "/v3/id-verification/wallets/ftn/": {
      "post": {
        "operationId": "start_ftn_wallet_verification",
        "x-didit-sdk": {
          "resource": "id_wallets",
          "method": "start_ftn",
          "auth": "api_key",
          "server": true
        },
        "description": "Mulai proses masuk Finnish Trust Network (bank dan operator seluler Finlandia (FTN); FIN) tanpa alur kerja apa pun. Ditagih sekali, hanya ketika identitas diverifikasi. Respons membawa next_action.type=redirect dengan URL tujuan browser pengguna; pengguna kembali ke return_url dengan request_id dan result yang ditambahkan. Baca hasilnya dengan GET /v3/id-verification/wallets/verifications/{request_id}/ atau dari webhook, jangan pernah dari URL. Aplikasi sandbox mendapatkan simulasi deterministik (simulated: true) yang tidak pernah menghubungi penyedia.",
        "summary": "Mulai verifikasi Finnish Trust Network",
        "parameters": [
          {
            "in": "header",
            "name": "Idempotency-Key",
            "schema": {
              "type": "string"
            },
            "description": "Kunci keamanan coba lagi opsional (maks 255 karakter). Mencoba lagi dengan kunci, dompet, dan body yang sama akan mengembalikan verifikasi asli tanpa memulai proses masuk kedua; kunci yang sama dengan dompet atau body lain akan mengembalikan 409 idempotency_key_reused."
          }
        ],
        "tags": [
          "Digital ID wallets"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiFtnWalletVerificationStartRequest"
              },
              "example": {
                "country": "FIN",
                "vendor_data": "your-customer-reference",
                "metadata": {
                  "reference": "example"
                },
                "return_url": "https://app.example.com/identity/complete"
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiFtnWalletVerificationStartRequest"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiFtnWalletVerificationStartRequest"
              }
            }
          },
          "required": true
        },
        "security": [
          {
            "ApiKeyAuth": []
          },
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationResponse"
                },
                "example": {
                  "request_id": "00000000-0000-4000-8000-000000000001",
                  "wallet_verification": {
                    "wallet": {
                      "id": "ftn",
                      "name": "Finnish Trust Network",
                      "issuing_authority": "Finnish banks and mobile operators (FTN)"
                    },
                    "country": "FIN",
                    "status": "Not Finished",
                    "outcome": "pending",
                    "error": null,
                    "interaction": "redirect",
                    "simulated": false,
                    "expires_at": "2026-01-01T10:10:00Z",
                    "next_action": {
                      "type": "redirect",
                      "url": "https://wallet.example.com/authorize"
                    },
                    "identity": null,
                    "attributes": null,
                    "level_of_assurance": null,
                    "verified_at": null,
                    "signature_valid": null,
                    "credential_type": "person_identification"
                  },
                  "vendor_data": "your-customer-reference",
                  "metadata": {
                    "reference": "example"
                  },
                  "created_at": "2026-01-01T10:00:00Z"
                }
              }
            },
            "description": ""
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationStartBadRequest"
                }
              }
            },
            "description": "Error validasi kolom ({field: [messages]}), atau error return_url_invalid, return_url_not_allowed, invalid_personal_code, invalid_phone_number, atau idempotency_key_invalid."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationStartForbidden"
                }
              }
            },
            "description": "Kredensial tidak ada ({detail}), atau kesalahan wallet_unavailable, insufficient_credits, atau contract_rate_missing."
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "kesalahan idempotency_key_reused atau idempotency_key_in_progress (dengan Retry-After)."
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "kesalahan wallet_provider_unavailable: penyedia tidak dapat memulai; tidak ada yang dibuat."
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "kesalahan wallet_not_configured: lingkungan ini tidak dapat menjangkau dompet."
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL",
            "source": "curl --request POST \\\n  --url https://verification.didit.me/v3/id-verification/wallets/ftn/ \\\n  --header 'x-api-key: YOUR_API_KEY' \\\n  --header 'Idempotency-Key: your-unique-attempt-key' \\\n  --header 'Content-Type: application/json' \\\n  --data '{\n  \"country\": \"FIN\",\n  \"vendor_data\": \"your-customer-reference\",\n  \"metadata\": {\n    \"reference\": \"example\"\n  },\n  \"return_url\": \"https://app.example.com/identity/complete\"\n}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.id_wallets.start_ftn(\n    vendor_data=\"your-customer-reference\",\n    metadata={\"reference\": \"example\"},\n    country=\"FIN\",\n    return_url=\"https://app.example.com/identity/complete\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.idWallets.startFtn({\n  vendor_data: \"your-customer-reference\",\n  metadata: { reference: \"example\" },\n  country: \"FIN\",\n  return_url: \"https://app.example.com/identity/complete\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.IDWallets.StartFtn(ctx, didit.IDWalletsStartFtnParams{\n\tBody: didit.DigitalIDWalletAPIFtnWalletVerificationStartRequest{\n\t\tVendorData: didit.String(\"your-customer-reference\"),\n\t\tMetadata:   didit.Some(map[string]any{\"reference\": \"example\"}),\n\t\tCountry:    didit.Some(didit.DigitalIDWalletAPIFtnWalletVerificationStartCountryEnum(\"FIN\")),\n\t\tReturnURL:  \"https://app.example.com/identity/complete\",\n\t},\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.DigitalIdWalletApiFtnWalletVerificationStartCountryEnum;\nimport me.didit.types.DigitalIdWalletApiFtnWalletVerificationStartRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.idWallets().startFtn(DigitalIdWalletApiFtnWalletVerificationStartRequest.builder()\n        .vendorData(\"your-customer-reference\")\n        .metadata(Map.of(\"reference\", \"example\"))\n        .country(DigitalIdWalletApiFtnWalletVerificationStartCountryEnum.of(\"FIN\"))\n        .returnUrl(\"https://app.example.com/identity/complete\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->idWallets->startFtn([\n    'vendor_data' => 'your-customer-reference',\n    'metadata' => ['reference' => 'example'],\n    'country' => 'FIN',\n    'return_url' => 'https://app.example.com/identity/complete',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.id_wallets.start_ftn(\n  vendor_data: \"your-customer-reference\",\n  metadata: { reference: \"example\" },\n  country: \"FIN\",\n  return_url: \"https://app.example.com/identity/complete\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.IdWallets.StartFtnAsync(new DigitalIdWalletApiFtnWalletVerificationStartRequest\n{\n    VendorData = \"your-customer-reference\",\n    Metadata = new Dictionary<string, object> { [\"reference\"] = \"example\" },\n    Country = new DigitalIdWalletApiFtnWalletVerificationStartCountryEnum(\"FIN\"),\n    ReturnUrl = \"https://app.example.com/identity/complete\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "x-didit-wallet-id": "ftn"
      }
    },
    "/v3/id-verification/wallets/personalausweis/": {
      "post": {
        "operationId": "start_personalausweis_wallet_verification",
        "x-didit-sdk": {
          "resource": "id_wallets",
          "method": "start_personalausweis",
          "auth": "api_key",
          "server": true
        },
        "description": "Mulai proses masuk Personalausweis (Bundesministerium des Innern (eID); DEU) tanpa alur kerja apa pun. Ditagih sekali, hanya saat identitas terverifikasi. Respons membawa next_action.type=redirect berisi URL tujuan pengalihan browser pengguna; pengguna kembali ke return_url dengan request_id dan result yang ditambahkan. Baca hasilnya dengan GET /v3/id-verification/wallets/verifications/{request_id}/ atau dari webhook, jangan pernah dari URL. Aplikasi sandbox mendapatkan simulasi deterministik (simulated: true) yang tidak pernah menghubungi penyedia.",
        "summary": "Mulai verifikasi Personalausweis",
        "parameters": [
          {
            "in": "header",
            "name": "Idempotency-Key",
            "schema": {
              "type": "string"
            },
            "description": "Kunci keamanan coba lagi opsional (maks 255 karakter). Mencoba lagi dengan kunci, dompet, dan body yang sama akan mengembalikan verifikasi asli tanpa memulai proses masuk kedua; kunci yang sama dengan dompet atau body lain akan mengembalikan 409 idempotency_key_reused."
          }
        ],
        "tags": [
          "Digital ID wallets"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiPersonalausweisWalletVerificationStartRequest"
              },
              "example": {
                "country": "DEU",
                "vendor_data": "your-customer-reference",
                "metadata": {
                  "reference": "example"
                },
                "return_url": "https://app.example.com/identity/complete"
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiPersonalausweisWalletVerificationStartRequest"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiPersonalausweisWalletVerificationStartRequest"
              }
            }
          },
          "required": true
        },
        "security": [
          {
            "ApiKeyAuth": []
          },
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationResponse"
                },
                "example": {
                  "request_id": "00000000-0000-4000-8000-000000000001",
                  "wallet_verification": {
                    "wallet": {
                      "id": "personalausweis",
                      "name": "Personalausweis",
                      "issuing_authority": "Bundesministerium des Innern (eID)"
                    },
                    "country": "DEU",
                    "status": "Not Finished",
                    "outcome": "pending",
                    "error": null,
                    "interaction": "redirect",
                    "simulated": false,
                    "expires_at": "2026-01-01T10:10:00Z",
                    "next_action": {
                      "type": "redirect",
                      "url": "https://wallet.example.com/authorize"
                    },
                    "identity": null,
                    "attributes": null,
                    "level_of_assurance": null,
                    "verified_at": null,
                    "signature_valid": null,
                    "credential_type": "person_identification"
                  },
                  "vendor_data": "your-customer-reference",
                  "metadata": {
                    "reference": "example"
                  },
                  "created_at": "2026-01-01T10:00:00Z"
                }
              }
            },
            "description": ""
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationStartBadRequest"
                }
              }
            },
            "description": "Error validasi kolom ({field: [messages]}), atau error return_url_invalid, return_url_not_allowed, invalid_personal_code, invalid_phone_number, atau idempotency_key_invalid."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationStartForbidden"
                }
              }
            },
            "description": "Kredensial tidak ada ({detail}), atau kesalahan wallet_unavailable, insufficient_credits, atau contract_rate_missing."
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "kesalahan idempotency_key_reused atau idempotency_key_in_progress (dengan Retry-After)."
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "kesalahan wallet_provider_unavailable: penyedia tidak dapat memulai; tidak ada yang dibuat."
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "kesalahan wallet_not_configured: lingkungan ini tidak dapat menjangkau dompet."
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL",
            "source": "curl --request POST \\\n  --url https://verification.didit.me/v3/id-verification/wallets/personalausweis/ \\\n  --header 'x-api-key: YOUR_API_KEY' \\\n  --header 'Idempotency-Key: your-unique-attempt-key' \\\n  --header 'Content-Type: application/json' \\\n  --data '{\n  \"country\": \"DEU\",\n  \"vendor_data\": \"your-customer-reference\",\n  \"metadata\": {\n    \"reference\": \"example\"\n  },\n  \"return_url\": \"https://app.example.com/identity/complete\"\n}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.id_wallets.start_personalausweis(\n    vendor_data=\"your-customer-reference\",\n    metadata={\"reference\": \"example\"},\n    country=\"DEU\",\n    return_url=\"https://app.example.com/identity/complete\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.idWallets.startPersonalausweis({\n  vendor_data: \"your-customer-reference\",\n  metadata: { reference: \"example\" },\n  country: \"DEU\",\n  return_url: \"https://app.example.com/identity/complete\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.IDWallets.StartPersonalausweis(ctx, didit.IDWalletsStartPersonalausweisParams{\n\tBody: didit.DigitalIDWalletAPIPersonalausweisWalletVerificationStartRequest{\n\t\tVendorData: didit.String(\"your-customer-reference\"),\n\t\tMetadata:   didit.Some(map[string]any{\"reference\": \"example\"}),\n\t\tCountry:    didit.Some(didit.DigitalIDWalletAPIPersonalausweisWalletVerificationStartCountryEnum(\"DEU\")),\n\t\tReturnURL:  \"https://app.example.com/identity/complete\",\n\t},\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.DigitalIdWalletApiPersonalausweisWalletVerificationStartCountryEnum;\nimport me.didit.types.DigitalIdWalletApiPersonalausweisWalletVerificationStartRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.idWallets().startPersonalausweis(DigitalIdWalletApiPersonalausweisWalletVerificationStartRequest.builder()\n        .vendorData(\"your-customer-reference\")\n        .metadata(Map.of(\"reference\", \"example\"))\n        .country(DigitalIdWalletApiPersonalausweisWalletVerificationStartCountryEnum.of(\"DEU\"))\n        .returnUrl(\"https://app.example.com/identity/complete\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->idWallets->startPersonalausweis([\n    'vendor_data' => 'your-customer-reference',\n    'metadata' => ['reference' => 'example'],\n    'country' => 'DEU',\n    'return_url' => 'https://app.example.com/identity/complete',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.id_wallets.start_personalausweis(\n  vendor_data: \"your-customer-reference\",\n  metadata: { reference: \"example\" },\n  country: \"DEU\",\n  return_url: \"https://app.example.com/identity/complete\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.IdWallets.StartPersonalausweisAsync(new DigitalIdWalletApiPersonalausweisWalletVerificationStartRequest\n{\n    VendorData = \"your-customer-reference\",\n    Metadata = new Dictionary<string, object> { [\"reference\"] = \"example\" },\n    Country = new DigitalIdWalletApiPersonalausweisWalletVerificationStartCountryEnum(\"DEU\"),\n    ReturnUrl = \"https://app.example.com/identity/complete\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "x-didit-wallet-id": "personalausweis"
      }
    },
    "/v3/id-verification/wallets/frejaid/": {
      "post": {
        "operationId": "start_frejaid_wallet_verification",
        "x-didit-sdk": {
          "resource": "id_wallets",
          "method": "start_frejaid",
          "auth": "api_key",
          "server": true
        },
        "description": "Mulai proses masuk Freja eID (Freja eID Group; SWE) tanpa alur kerja apa pun. Ditagih sekali, hanya ketika identitas diverifikasi. Respons membawa next_action.type=redirect dengan URL tujuan browser pengguna; pengguna kembali ke return_url dengan request_id dan result yang ditambahkan. Baca hasilnya dengan GET /v3/id-verification/wallets/verifications/{request_id}/ atau dari webhook, jangan pernah dari URL. Aplikasi sandbox mendapatkan simulasi deterministik (simulated: true) yang tidak pernah menghubungi penyedia.",
        "summary": "Mulai verifikasi Freja eID",
        "parameters": [
          {
            "in": "header",
            "name": "Idempotency-Key",
            "schema": {
              "type": "string"
            },
            "description": "Kunci keamanan coba lagi opsional (maks 255 karakter). Mencoba lagi dengan kunci, dompet, dan body yang sama akan mengembalikan verifikasi asli tanpa memulai proses masuk kedua; kunci yang sama dengan dompet atau body lain akan mengembalikan 409 idempotency_key_reused."
          }
        ],
        "tags": [
          "Digital ID wallets"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiFrejaidWalletVerificationStartRequest"
              },
              "example": {
                "country": "SWE",
                "vendor_data": "your-customer-reference",
                "metadata": {
                  "reference": "example"
                },
                "return_url": "https://app.example.com/identity/complete"
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiFrejaidWalletVerificationStartRequest"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiFrejaidWalletVerificationStartRequest"
              }
            }
          },
          "required": true
        },
        "security": [
          {
            "ApiKeyAuth": []
          },
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationResponse"
                },
                "example": {
                  "request_id": "00000000-0000-4000-8000-000000000001",
                  "wallet_verification": {
                    "wallet": {
                      "id": "frejaid",
                      "name": "Freja eID",
                      "issuing_authority": "Freja eID Group"
                    },
                    "country": "SWE",
                    "status": "Not Finished",
                    "outcome": "pending",
                    "error": null,
                    "interaction": "redirect",
                    "simulated": false,
                    "expires_at": "2026-01-01T10:10:00Z",
                    "next_action": {
                      "type": "redirect",
                      "url": "https://wallet.example.com/authorize"
                    },
                    "identity": null,
                    "attributes": null,
                    "level_of_assurance": null,
                    "verified_at": null,
                    "signature_valid": null,
                    "credential_type": "person_identification"
                  },
                  "vendor_data": "your-customer-reference",
                  "metadata": {
                    "reference": "example"
                  },
                  "created_at": "2026-01-01T10:00:00Z"
                }
              }
            },
            "description": ""
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationStartBadRequest"
                }
              }
            },
            "description": "Error validasi kolom ({field: [messages]}), atau error return_url_invalid, return_url_not_allowed, invalid_personal_code, invalid_phone_number, atau idempotency_key_invalid."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationStartForbidden"
                }
              }
            },
            "description": "Kredensial tidak ada ({detail}), atau kesalahan wallet_unavailable, insufficient_credits, atau contract_rate_missing."
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "kesalahan idempotency_key_reused atau idempotency_key_in_progress (dengan Retry-After)."
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "kesalahan wallet_provider_unavailable: penyedia tidak dapat memulai; tidak ada yang dibuat."
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "kesalahan wallet_not_configured: lingkungan ini tidak dapat menjangkau dompet."
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL",
            "source": "curl --request POST \\\n  --url https://verification.didit.me/v3/id-verification/wallets/frejaid/ \\\n  --header 'x-api-key: YOUR_API_KEY' \\\n  --header 'Idempotency-Key: your-unique-attempt-key' \\\n  --header 'Content-Type: application/json' \\\n  --data '{\n  \"country\": \"SWE\",\n  \"vendor_data\": \"your-customer-reference\",\n  \"metadata\": {\n    \"reference\": \"example\"\n  },\n  \"return_url\": \"https://app.example.com/identity/complete\"\n}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.id_wallets.start_frejaid(\n    vendor_data=\"your-customer-reference\",\n    metadata={\"reference\": \"example\"},\n    country=\"SWE\",\n    return_url=\"https://app.example.com/identity/complete\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.idWallets.startFrejaid({\n  vendor_data: \"your-customer-reference\",\n  metadata: { reference: \"example\" },\n  country: \"SWE\",\n  return_url: \"https://app.example.com/identity/complete\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.IDWallets.StartFrejaid(ctx, didit.IDWalletsStartFrejaidParams{\n\tBody: didit.DigitalIDWalletAPIFrejaidWalletVerificationStartRequest{\n\t\tVendorData: didit.String(\"your-customer-reference\"),\n\t\tMetadata:   didit.Some(map[string]any{\"reference\": \"example\"}),\n\t\tCountry:    didit.Some(didit.DigitalIDWalletAPICountryEe9enum(\"SWE\")),\n\t\tReturnURL:  \"https://app.example.com/identity/complete\",\n\t},\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.DigitalIdWalletApiCountryEe9Enum;\nimport me.didit.types.DigitalIdWalletApiFrejaidWalletVerificationStartRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.idWallets().startFrejaid(DigitalIdWalletApiFrejaidWalletVerificationStartRequest.builder()\n        .vendorData(\"your-customer-reference\")\n        .metadata(Map.of(\"reference\", \"example\"))\n        .country(DigitalIdWalletApiCountryEe9Enum.of(\"SWE\"))\n        .returnUrl(\"https://app.example.com/identity/complete\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->idWallets->startFrejaid([\n    'vendor_data' => 'your-customer-reference',\n    'metadata' => ['reference' => 'example'],\n    'country' => 'SWE',\n    'return_url' => 'https://app.example.com/identity/complete',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.id_wallets.start_frejaid(\n  vendor_data: \"your-customer-reference\",\n  metadata: { reference: \"example\" },\n  country: \"SWE\",\n  return_url: \"https://app.example.com/identity/complete\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.IdWallets.StartFrejaidAsync(new DigitalIdWalletApiFrejaidWalletVerificationStartRequest\n{\n    VendorData = \"your-customer-reference\",\n    Metadata = new Dictionary<string, object> { [\"reference\"] = \"example\" },\n    Country = new DigitalIdWalletApiCountryEe9Enum(\"SWE\"),\n    ReturnUrl = \"https://app.example.com/identity/complete\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "x-didit-wallet-id": "frejaid"
      }
    },
    "/v3/id-verification/wallets/uae-pass/": {
      "post": {
        "operationId": "start_uae_pass_wallet_verification",
        "x-didit-sdk": {
          "resource": "id_wallets",
          "method": "start_uae_pass",
          "auth": "api_key",
          "server": true
        },
        "description": "Mulai proses masuk UAE PASS (UAE Digital Government Authority; ARE) tanpa alur kerja apa pun. Ditagih sekali, hanya saat identitas terverifikasi. Respons membawa next_action.type=redirect berisi URL tujuan pengalihan browser pengguna; pengguna kembali ke return_url dengan request_id dan result yang ditambahkan. Baca hasilnya dengan GET /v3/id-verification/wallets/verifications/{request_id}/ atau dari webhook, jangan pernah dari URL. Aplikasi sandbox mendapatkan simulasi deterministik (simulated: true) yang tidak pernah menghubungi penyedia.",
        "summary": "Mulai verifikasi UAE PASS",
        "parameters": [
          {
            "in": "header",
            "name": "Idempotency-Key",
            "schema": {
              "type": "string"
            },
            "description": "Kunci keamanan coba lagi opsional (maks 255 karakter). Mencoba lagi dengan kunci, dompet, dan body yang sama akan mengembalikan verifikasi asli tanpa memulai proses masuk kedua; kunci yang sama dengan dompet atau body lain akan mengembalikan 409 idempotency_key_reused."
          }
        ],
        "tags": [
          "Digital ID wallets"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiUaePassWalletVerificationStartRequest"
              },
              "example": {
                "country": "ARE",
                "vendor_data": "your-customer-reference",
                "metadata": {
                  "reference": "example"
                },
                "return_url": "https://app.example.com/identity/complete"
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiUaePassWalletVerificationStartRequest"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiUaePassWalletVerificationStartRequest"
              }
            }
          },
          "required": true
        },
        "security": [
          {
            "ApiKeyAuth": []
          },
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationResponse"
                },
                "example": {
                  "request_id": "00000000-0000-4000-8000-000000000001",
                  "wallet_verification": {
                    "wallet": {
                      "id": "uae_pass",
                      "name": "UAE PASS",
                      "issuing_authority": "UAE Digital Government Authority"
                    },
                    "country": "ARE",
                    "status": "Not Finished",
                    "outcome": "pending",
                    "error": null,
                    "interaction": "redirect",
                    "simulated": false,
                    "expires_at": "2026-01-01T10:10:00Z",
                    "next_action": {
                      "type": "redirect",
                      "url": "https://wallet.example.com/authorize"
                    },
                    "identity": null,
                    "attributes": null,
                    "level_of_assurance": null,
                    "verified_at": null,
                    "signature_valid": null,
                    "credential_type": "person_identification"
                  },
                  "vendor_data": "your-customer-reference",
                  "metadata": {
                    "reference": "example"
                  },
                  "created_at": "2026-01-01T10:00:00Z"
                }
              }
            },
            "description": ""
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationStartBadRequest"
                }
              }
            },
            "description": "Error validasi kolom ({field: [messages]}), atau error return_url_invalid, return_url_not_allowed, invalid_personal_code, invalid_phone_number, atau idempotency_key_invalid."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationStartForbidden"
                }
              }
            },
            "description": "Kredensial tidak ada ({detail}), atau kesalahan wallet_unavailable, insufficient_credits, atau contract_rate_missing."
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "kesalahan idempotency_key_reused atau idempotency_key_in_progress (dengan Retry-After)."
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "kesalahan wallet_provider_unavailable: penyedia tidak dapat memulai; tidak ada yang dibuat."
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "kesalahan wallet_not_configured: lingkungan ini tidak dapat menjangkau dompet."
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL",
            "source": "curl --request POST \\\n  --url https://verification.didit.me/v3/id-verification/wallets/uae-pass/ \\\n  --header 'x-api-key: YOUR_API_KEY' \\\n  --header 'Idempotency-Key: your-unique-attempt-key' \\\n  --header 'Content-Type: application/json' \\\n  --data '{\n  \"country\": \"ARE\",\n  \"vendor_data\": \"your-customer-reference\",\n  \"metadata\": {\n    \"reference\": \"example\"\n  },\n  \"return_url\": \"https://app.example.com/identity/complete\"\n}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.id_wallets.start_uae_pass(\n    vendor_data=\"your-customer-reference\",\n    metadata={\"reference\": \"example\"},\n    country=\"ARE\",\n    return_url=\"https://app.example.com/identity/complete\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.idWallets.startUaePass({\n  vendor_data: \"your-customer-reference\",\n  metadata: { reference: \"example\" },\n  country: \"ARE\",\n  return_url: \"https://app.example.com/identity/complete\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.IDWallets.StartUaePass(ctx, didit.IDWalletsStartUaePassParams{\n\tBody: didit.DigitalIDWalletAPIUaePassWalletVerificationStartRequest{\n\t\tVendorData: didit.String(\"your-customer-reference\"),\n\t\tMetadata:   didit.Some(map[string]any{\"reference\": \"example\"}),\n\t\tCountry:    didit.Some(didit.DigitalIDWalletAPIUaePassWalletVerificationStartCountryEnum(\"ARE\")),\n\t\tReturnURL:  \"https://app.example.com/identity/complete\",\n\t},\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.DigitalIdWalletApiUaePassWalletVerificationStartCountryEnum;\nimport me.didit.types.DigitalIdWalletApiUaePassWalletVerificationStartRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.idWallets().startUaePass(DigitalIdWalletApiUaePassWalletVerificationStartRequest.builder()\n        .vendorData(\"your-customer-reference\")\n        .metadata(Map.of(\"reference\", \"example\"))\n        .country(DigitalIdWalletApiUaePassWalletVerificationStartCountryEnum.of(\"ARE\"))\n        .returnUrl(\"https://app.example.com/identity/complete\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->idWallets->startUaePass([\n    'vendor_data' => 'your-customer-reference',\n    'metadata' => ['reference' => 'example'],\n    'country' => 'ARE',\n    'return_url' => 'https://app.example.com/identity/complete',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.id_wallets.start_uae_pass(\n  vendor_data: \"your-customer-reference\",\n  metadata: { reference: \"example\" },\n  country: \"ARE\",\n  return_url: \"https://app.example.com/identity/complete\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.IdWallets.StartUaePassAsync(new DigitalIdWalletApiUaePassWalletVerificationStartRequest\n{\n    VendorData = \"your-customer-reference\",\n    Metadata = new Dictionary<string, object> { [\"reference\"] = \"example\" },\n    Country = new DigitalIdWalletApiUaePassWalletVerificationStartCountryEnum(\"ARE\"),\n    ReturnUrl = \"https://app.example.com/identity/complete\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "x-didit-wallet-id": "uae_pass"
      }
    },
    "/v3/id-verification/wallets/govbr/": {
      "post": {
        "operationId": "start_govbr_wallet_verification",
        "x-didit-sdk": {
          "resource": "id_wallets",
          "method": "start_govbr",
          "auth": "api_key",
          "server": true
        },
        "description": "Mulai proses masuk gov.br (Governo Federal do Brasil; BRA) tanpa alur kerja apa pun. Ditagih sekali, hanya saat identitas terverifikasi. Respons membawa next_action.type=redirect berisi URL tujuan pengalihan browser pengguna; pengguna kembali ke return_url dengan request_id dan result yang ditambahkan. Baca hasilnya dengan GET /v3/id-verification/wallets/verifications/{request_id}/ atau dari webhook, jangan pernah dari URL. Aplikasi sandbox mendapatkan simulasi deterministik (simulated: true) yang tidak pernah menghubungi penyedia.",
        "summary": "Mulai verifikasi gov.br",
        "parameters": [
          {
            "in": "header",
            "name": "Idempotency-Key",
            "schema": {
              "type": "string"
            },
            "description": "Kunci keamanan coba lagi opsional (maks 255 karakter). Mencoba lagi dengan kunci, dompet, dan body yang sama akan mengembalikan verifikasi asli tanpa memulai proses masuk kedua; kunci yang sama dengan dompet atau body lain akan mengembalikan 409 idempotency_key_reused."
          }
        ],
        "tags": [
          "Digital ID wallets"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiGovbrWalletVerificationStartRequest"
              },
              "example": {
                "country": "BRA",
                "vendor_data": "your-customer-reference",
                "metadata": {
                  "reference": "example"
                },
                "return_url": "https://app.example.com/identity/complete"
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiGovbrWalletVerificationStartRequest"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiGovbrWalletVerificationStartRequest"
              }
            }
          },
          "required": true
        },
        "security": [
          {
            "ApiKeyAuth": []
          },
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationResponse"
                },
                "example": {
                  "request_id": "00000000-0000-4000-8000-000000000001",
                  "wallet_verification": {
                    "wallet": {
                      "id": "govbr",
                      "name": "gov.br",
                      "issuing_authority": "Governo Federal do Brasil"
                    },
                    "country": "BRA",
                    "status": "Not Finished",
                    "outcome": "pending",
                    "error": null,
                    "interaction": "redirect",
                    "simulated": false,
                    "expires_at": "2026-01-01T10:10:00Z",
                    "next_action": {
                      "type": "redirect",
                      "url": "https://wallet.example.com/authorize"
                    },
                    "identity": null,
                    "attributes": null,
                    "level_of_assurance": null,
                    "verified_at": null,
                    "signature_valid": null,
                    "credential_type": "person_identification"
                  },
                  "vendor_data": "your-customer-reference",
                  "metadata": {
                    "reference": "example"
                  },
                  "created_at": "2026-01-01T10:00:00Z"
                }
              }
            },
            "description": ""
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationStartBadRequest"
                }
              }
            },
            "description": "Error validasi kolom ({field: [messages]}), atau error return_url_invalid, return_url_not_allowed, invalid_personal_code, invalid_phone_number, atau idempotency_key_invalid."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationStartForbidden"
                }
              }
            },
            "description": "Kredensial tidak ada ({detail}), atau kesalahan wallet_unavailable, insufficient_credits, atau contract_rate_missing."
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "kesalahan idempotency_key_reused atau idempotency_key_in_progress (dengan Retry-After)."
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "kesalahan wallet_provider_unavailable: penyedia tidak dapat memulai; tidak ada yang dibuat."
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "kesalahan wallet_not_configured: lingkungan ini tidak dapat menjangkau dompet."
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL",
            "source": "curl --request POST \\\n  --url https://verification.didit.me/v3/id-verification/wallets/govbr/ \\\n  --header 'x-api-key: YOUR_API_KEY' \\\n  --header 'Idempotency-Key: your-unique-attempt-key' \\\n  --header 'Content-Type: application/json' \\\n  --data '{\n  \"country\": \"BRA\",\n  \"vendor_data\": \"your-customer-reference\",\n  \"metadata\": {\n    \"reference\": \"example\"\n  },\n  \"return_url\": \"https://app.example.com/identity/complete\"\n}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.id_wallets.start_govbr(\n    vendor_data=\"your-customer-reference\",\n    metadata={\"reference\": \"example\"},\n    country=\"BRA\",\n    return_url=\"https://app.example.com/identity/complete\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.idWallets.startGovbr({\n  vendor_data: \"your-customer-reference\",\n  metadata: { reference: \"example\" },\n  country: \"BRA\",\n  return_url: \"https://app.example.com/identity/complete\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.IDWallets.StartGovbr(ctx, didit.IDWalletsStartGovbrParams{\n\tBody: didit.DigitalIDWalletAPIGovbrWalletVerificationStartRequest{\n\t\tVendorData: didit.String(\"your-customer-reference\"),\n\t\tMetadata:   didit.Some(map[string]any{\"reference\": \"example\"}),\n\t\tCountry:    didit.Some(didit.DigitalIDWalletAPIGovbrWalletVerificationStartCountryEnum(\"BRA\")),\n\t\tReturnURL:  \"https://app.example.com/identity/complete\",\n\t},\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.DigitalIdWalletApiGovbrWalletVerificationStartCountryEnum;\nimport me.didit.types.DigitalIdWalletApiGovbrWalletVerificationStartRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.idWallets().startGovbr(DigitalIdWalletApiGovbrWalletVerificationStartRequest.builder()\n        .vendorData(\"your-customer-reference\")\n        .metadata(Map.of(\"reference\", \"example\"))\n        .country(DigitalIdWalletApiGovbrWalletVerificationStartCountryEnum.of(\"BRA\"))\n        .returnUrl(\"https://app.example.com/identity/complete\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->idWallets->startGovbr([\n    'vendor_data' => 'your-customer-reference',\n    'metadata' => ['reference' => 'example'],\n    'country' => 'BRA',\n    'return_url' => 'https://app.example.com/identity/complete',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.id_wallets.start_govbr(\n  vendor_data: \"your-customer-reference\",\n  metadata: { reference: \"example\" },\n  country: \"BRA\",\n  return_url: \"https://app.example.com/identity/complete\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.IdWallets.StartGovbrAsync(new DigitalIdWalletApiGovbrWalletVerificationStartRequest\n{\n    VendorData = \"your-customer-reference\",\n    Metadata = new Dictionary<string, object> { [\"reference\"] = \"example\" },\n    Country = new DigitalIdWalletApiGovbrWalletVerificationStartCountryEnum(\"BRA\"),\n    ReturnUrl = \"https://app.example.com/identity/complete\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "x-didit-wallet-id": "govbr"
      }
    },
    "/v3/id-verification/wallets/oneid/": {
      "post": {
        "operationId": "start_oneid_wallet_verification",
        "x-didit-sdk": {
          "resource": "id_wallets",
          "method": "start_oneid",
          "auth": "api_key",
          "server": true
        },
        "description": "Mulai proses masuk OneID (OneID (identitas terverifikasi bank Inggris); GBR) tanpa alur kerja apa pun. Ditagih sekali, hanya saat identitas terverifikasi. Respons membawa next_action.type=redirect berisi URL tujuan pengalihan browser pengguna; pengguna kembali ke return_url dengan request_id dan result yang ditambahkan. Baca hasilnya dengan GET /v3/id-verification/wallets/verifications/{request_id}/ atau dari webhook, jangan pernah dari URL. Aplikasi sandbox mendapatkan simulasi deterministik (simulated: true) yang tidak pernah menghubungi penyedia.",
        "summary": "Mulai verifikasi OneID",
        "parameters": [
          {
            "in": "header",
            "name": "Idempotency-Key",
            "schema": {
              "type": "string"
            },
            "description": "Kunci keamanan coba lagi opsional (maks 255 karakter). Mencoba lagi dengan kunci, dompet, dan body yang sama akan mengembalikan verifikasi asli tanpa memulai proses masuk kedua; kunci yang sama dengan dompet atau body lain akan mengembalikan 409 idempotency_key_reused."
          }
        ],
        "tags": [
          "Digital ID wallets"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiOneidWalletVerificationStartRequest"
              },
              "example": {
                "country": "GBR",
                "vendor_data": "your-customer-reference",
                "metadata": {
                  "reference": "example"
                },
                "return_url": "https://app.example.com/identity/complete"
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiOneidWalletVerificationStartRequest"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiOneidWalletVerificationStartRequest"
              }
            }
          },
          "required": true
        },
        "security": [
          {
            "ApiKeyAuth": []
          },
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationResponse"
                },
                "example": {
                  "request_id": "00000000-0000-4000-8000-000000000001",
                  "wallet_verification": {
                    "wallet": {
                      "id": "oneid",
                      "name": "OneID",
                      "issuing_authority": "OneID (UK bank-verified identity)"
                    },
                    "country": "GBR",
                    "status": "Not Finished",
                    "outcome": "pending",
                    "error": null,
                    "interaction": "redirect",
                    "simulated": false,
                    "expires_at": "2026-01-01T10:10:00Z",
                    "next_action": {
                      "type": "redirect",
                      "url": "https://wallet.example.com/authorize"
                    },
                    "identity": null,
                    "attributes": null,
                    "level_of_assurance": null,
                    "verified_at": null,
                    "signature_valid": null,
                    "credential_type": "person_identification"
                  },
                  "vendor_data": "your-customer-reference",
                  "metadata": {
                    "reference": "example"
                  },
                  "created_at": "2026-01-01T10:00:00Z"
                }
              }
            },
            "description": ""
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationStartBadRequest"
                }
              }
            },
            "description": "Error validasi kolom ({field: [messages]}), atau error return_url_invalid, return_url_not_allowed, invalid_personal_code, invalid_phone_number, atau idempotency_key_invalid."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationStartForbidden"
                }
              }
            },
            "description": "Kredensial tidak ada ({detail}), atau kesalahan wallet_unavailable, insufficient_credits, atau contract_rate_missing."
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "kesalahan idempotency_key_reused atau idempotency_key_in_progress (dengan Retry-After)."
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "kesalahan wallet_provider_unavailable: penyedia tidak dapat memulai; tidak ada yang dibuat."
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "kesalahan wallet_not_configured: lingkungan ini tidak dapat menjangkau dompet."
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL",
            "source": "curl --request POST \\\n  --url https://verification.didit.me/v3/id-verification/wallets/oneid/ \\\n  --header 'x-api-key: YOUR_API_KEY' \\\n  --header 'Idempotency-Key: your-unique-attempt-key' \\\n  --header 'Content-Type: application/json' \\\n  --data '{\n  \"country\": \"GBR\",\n  \"vendor_data\": \"your-customer-reference\",\n  \"metadata\": {\n    \"reference\": \"example\"\n  },\n  \"return_url\": \"https://app.example.com/identity/complete\"\n}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.id_wallets.start_oneid(\n    vendor_data=\"your-customer-reference\",\n    metadata={\"reference\": \"example\"},\n    country=\"GBR\",\n    return_url=\"https://app.example.com/identity/complete\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.idWallets.startOneid({\n  vendor_data: \"your-customer-reference\",\n  metadata: { reference: \"example\" },\n  country: \"GBR\",\n  return_url: \"https://app.example.com/identity/complete\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.IDWallets.StartOneid(ctx, didit.IDWalletsStartOneidParams{\n\tBody: didit.DigitalIDWalletAPIOneidWalletVerificationStartRequest{\n\t\tVendorData: didit.String(\"your-customer-reference\"),\n\t\tMetadata:   didit.Some(map[string]any{\"reference\": \"example\"}),\n\t\tCountry:    didit.Some(didit.DigitalIDWalletAPICountry520enum(\"GBR\")),\n\t\tReturnURL:  \"https://app.example.com/identity/complete\",\n\t},\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.DigitalIdWalletApiCountry520Enum;\nimport me.didit.types.DigitalIdWalletApiOneidWalletVerificationStartRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.idWallets().startOneid(DigitalIdWalletApiOneidWalletVerificationStartRequest.builder()\n        .vendorData(\"your-customer-reference\")\n        .metadata(Map.of(\"reference\", \"example\"))\n        .country(DigitalIdWalletApiCountry520Enum.of(\"GBR\"))\n        .returnUrl(\"https://app.example.com/identity/complete\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->idWallets->startOneid([\n    'vendor_data' => 'your-customer-reference',\n    'metadata' => ['reference' => 'example'],\n    'country' => 'GBR',\n    'return_url' => 'https://app.example.com/identity/complete',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.id_wallets.start_oneid(\n  vendor_data: \"your-customer-reference\",\n  metadata: { reference: \"example\" },\n  country: \"GBR\",\n  return_url: \"https://app.example.com/identity/complete\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.IdWallets.StartOneidAsync(new DigitalIdWalletApiOneidWalletVerificationStartRequest\n{\n    VendorData = \"your-customer-reference\",\n    Metadata = new Dictionary<string, object> { [\"reference\"] = \"example\" },\n    Country = new DigitalIdWalletApiCountry520Enum(\"GBR\"),\n    ReturnUrl = \"https://app.example.com/identity/complete\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "x-didit-wallet-id": "oneid"
      }
    },
    "/v3/id-verification/wallets/govuk-wallet/": {
      "post": {
        "operationId": "start_govuk_wallet_wallet_verification",
        "x-didit-sdk": {
          "resource": "id_wallets",
          "method": "start_govuk_wallet",
          "auth": "api_key",
          "server": true
        },
        "description": "Mulai proses masuk GOV.UK Wallet (UK Government Digital Service; GBR) tanpa alur kerja apa pun. Ditagih sekali, hanya ketika identitas diverifikasi. Respons membawa next_action.type=redirect dengan URL tujuan browser pengguna; pengguna kembali ke return_url dengan request_id dan result yang ditambahkan. Baca hasilnya dengan GET /v3/id-verification/wallets/verifications/{request_id}/ atau dari webhook, jangan pernah dari URL. Aplikasi sandbox mendapatkan simulasi deterministik (simulated: true) yang tidak pernah menghubungi penyedia.",
        "summary": "Mulai verifikasi GOV.UK Wallet",
        "parameters": [
          {
            "in": "header",
            "name": "Idempotency-Key",
            "schema": {
              "type": "string"
            },
            "description": "Kunci keamanan coba lagi opsional (maks 255 karakter). Mencoba lagi dengan kunci, dompet, dan body yang sama akan mengembalikan verifikasi asli tanpa memulai proses masuk kedua; kunci yang sama dengan dompet atau body lain akan mengembalikan 409 idempotency_key_reused."
          }
        ],
        "tags": [
          "Digital ID wallets"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiGovukWalletWalletVerificationStartRequest"
              },
              "example": {
                "country": "GBR",
                "vendor_data": "your-customer-reference",
                "metadata": {
                  "reference": "example"
                },
                "return_url": "https://app.example.com/identity/complete"
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiGovukWalletWalletVerificationStartRequest"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiGovukWalletWalletVerificationStartRequest"
              }
            }
          },
          "required": true
        },
        "security": [
          {
            "ApiKeyAuth": []
          },
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationResponse"
                },
                "example": {
                  "request_id": "00000000-0000-4000-8000-000000000001",
                  "wallet_verification": {
                    "wallet": {
                      "id": "govuk_wallet",
                      "name": "GOV.UK Wallet",
                      "issuing_authority": "UK Government Digital Service"
                    },
                    "country": "GBR",
                    "status": "Not Finished",
                    "outcome": "pending",
                    "error": null,
                    "interaction": "redirect",
                    "simulated": false,
                    "expires_at": "2026-01-01T10:10:00Z",
                    "next_action": {
                      "type": "redirect",
                      "url": "https://wallet.example.com/authorize"
                    },
                    "identity": null,
                    "attributes": null,
                    "level_of_assurance": null,
                    "verified_at": null,
                    "signature_valid": null,
                    "credential_type": "person_identification"
                  },
                  "vendor_data": "your-customer-reference",
                  "metadata": {
                    "reference": "example"
                  },
                  "created_at": "2026-01-01T10:00:00Z"
                }
              }
            },
            "description": ""
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationStartBadRequest"
                }
              }
            },
            "description": "Error validasi kolom ({field: [messages]}), atau error return_url_invalid, return_url_not_allowed, invalid_personal_code, invalid_phone_number, atau idempotency_key_invalid."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationStartForbidden"
                }
              }
            },
            "description": "Kredensial tidak ada ({detail}), atau kesalahan wallet_unavailable, insufficient_credits, atau contract_rate_missing."
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "kesalahan idempotency_key_reused atau idempotency_key_in_progress (dengan Retry-After)."
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "kesalahan wallet_provider_unavailable: penyedia tidak dapat memulai; tidak ada yang dibuat."
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "kesalahan wallet_not_configured: lingkungan ini tidak dapat menjangkau dompet."
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL",
            "source": "curl --request POST \\\n  --url https://verification.didit.me/v3/id-verification/wallets/govuk-wallet/ \\\n  --header 'x-api-key: YOUR_API_KEY' \\\n  --header 'Idempotency-Key: your-unique-attempt-key' \\\n  --header 'Content-Type: application/json' \\\n  --data '{\n  \"country\": \"GBR\",\n  \"vendor_data\": \"your-customer-reference\",\n  \"metadata\": {\n    \"reference\": \"example\"\n  },\n  \"return_url\": \"https://app.example.com/identity/complete\"\n}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.id_wallets.start_govuk_wallet(\n    vendor_data=\"your-customer-reference\",\n    metadata={\"reference\": \"example\"},\n    country=\"GBR\",\n    return_url=\"https://app.example.com/identity/complete\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.idWallets.startGovukWallet({\n  vendor_data: \"your-customer-reference\",\n  metadata: { reference: \"example\" },\n  country: \"GBR\",\n  return_url: \"https://app.example.com/identity/complete\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.IDWallets.StartGovukWallet(ctx, didit.IDWalletsStartGovukWalletParams{\n\tBody: didit.DigitalIDWalletAPIGovukWalletWalletVerificationStartRequest{\n\t\tVendorData: didit.String(\"your-customer-reference\"),\n\t\tMetadata:   didit.Some(map[string]any{\"reference\": \"example\"}),\n\t\tCountry:    didit.Some(didit.DigitalIDWalletAPICountry520enum(\"GBR\")),\n\t\tReturnURL:  \"https://app.example.com/identity/complete\",\n\t},\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.DigitalIdWalletApiCountry520Enum;\nimport me.didit.types.DigitalIdWalletApiGovukWalletWalletVerificationStartRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.idWallets().startGovukWallet(DigitalIdWalletApiGovukWalletWalletVerificationStartRequest.builder()\n        .vendorData(\"your-customer-reference\")\n        .metadata(Map.of(\"reference\", \"example\"))\n        .country(DigitalIdWalletApiCountry520Enum.of(\"GBR\"))\n        .returnUrl(\"https://app.example.com/identity/complete\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->idWallets->startGovukWallet([\n    'vendor_data' => 'your-customer-reference',\n    'metadata' => ['reference' => 'example'],\n    'country' => 'GBR',\n    'return_url' => 'https://app.example.com/identity/complete',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.id_wallets.start_govuk_wallet(\n  vendor_data: \"your-customer-reference\",\n  metadata: { reference: \"example\" },\n  country: \"GBR\",\n  return_url: \"https://app.example.com/identity/complete\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.IdWallets.StartGovukWalletAsync(new DigitalIdWalletApiGovukWalletWalletVerificationStartRequest\n{\n    VendorData = \"your-customer-reference\",\n    Metadata = new Dictionary<string, object> { [\"reference\"] = \"example\" },\n    Country = new DigitalIdWalletApiCountry520Enum(\"GBR\"),\n    ReturnUrl = \"https://app.example.com/identity/complete\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "x-didit-wallet-id": "govuk_wallet"
      }
    },
    "/v3/id-verification/wallets/smart-id/": {
      "post": {
        "operationId": "start_smart_id_wallet_verification",
        "x-didit-sdk": {
          "resource": "id_wallets",
          "method": "start_smart_id",
          "auth": "api_key",
          "server": true
        },
        "description": "Mulai proses masuk Smart-ID (SK ID Solutions; EST, LVA, LTU, BEL) tanpa alur kerja apa pun. Ditagih sekali, hanya saat identitas terverifikasi. Respons membawa next_action.type=confirm_in_app berisi kode perbandingan untuk ditampilkan kepada pengguna; pengguna mengonfirmasinya dan memasukkan PIN mereka di aplikasi (jangan pernah mengumpulkan PIN). Lakukan polling POST /v3/id-verification/wallets/verifications/{request_id}/poll/ setiap poll_interval_seconds, atau andalkan webhook: Didit juga melakukan polling di latar belakang. Aplikasi sandbox mendapatkan simulasi deterministik (simulated: true) yang tidak pernah menghubungi penyedia.",
        "summary": "Mulai verifikasi Smart-ID",
        "parameters": [
          {
            "in": "header",
            "name": "Idempotency-Key",
            "schema": {
              "type": "string"
            },
            "description": "Kunci keamanan coba lagi opsional (maks 255 karakter). Mencoba lagi dengan kunci, dompet, dan body yang sama akan mengembalikan verifikasi asli tanpa memulai proses masuk kedua; kunci yang sama dengan dompet atau body lain akan mengembalikan 409 idempotency_key_reused."
          }
        ],
        "tags": [
          "Digital ID wallets"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiSmartIdWalletVerificationStartRequest"
              },
              "example": {
                "country": "EST",
                "vendor_data": "your-customer-reference",
                "metadata": {
                  "reference": "example"
                },
                "personal_code": "00000000000"
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiSmartIdWalletVerificationStartRequest"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiSmartIdWalletVerificationStartRequest"
              }
            }
          },
          "required": true
        },
        "security": [
          {
            "ApiKeyAuth": []
          },
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationResponse"
                },
                "example": {
                  "request_id": "00000000-0000-4000-8000-000000000001",
                  "wallet_verification": {
                    "wallet": {
                      "id": "smart_id",
                      "name": "Smart-ID",
                      "issuing_authority": "SK ID Solutions"
                    },
                    "country": "EST",
                    "status": "Not Finished",
                    "outcome": "pending",
                    "error": null,
                    "interaction": "in_app",
                    "simulated": true,
                    "expires_at": "2026-01-01T10:10:00Z",
                    "next_action": {
                      "type": "confirm_in_app",
                      "verification_code": "1234",
                      "poll_interval_seconds": 2
                    },
                    "identity": null,
                    "attributes": null,
                    "level_of_assurance": null,
                    "verified_at": null,
                    "signature_valid": null,
                    "credential_type": "person_identification"
                  },
                  "vendor_data": "your-customer-reference",
                  "metadata": {
                    "reference": "example"
                  },
                  "created_at": "2026-01-01T10:00:00Z"
                }
              }
            },
            "description": ""
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationStartBadRequest"
                }
              }
            },
            "description": "Error validasi kolom ({field: [messages]}), atau error return_url_invalid, return_url_not_allowed, invalid_personal_code, invalid_phone_number, atau idempotency_key_invalid."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationStartForbidden"
                }
              }
            },
            "description": "Kredensial tidak ada ({detail}), atau kesalahan wallet_unavailable, insufficient_credits, atau contract_rate_missing."
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "kesalahan idempotency_key_reused atau idempotency_key_in_progress (dengan Retry-After)."
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "kesalahan wallet_provider_unavailable: penyedia tidak dapat memulai; tidak ada yang dibuat."
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "kesalahan wallet_not_configured: lingkungan ini tidak dapat menjangkau dompet."
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL",
            "source": "curl --request POST \\\n  --url https://verification.didit.me/v3/id-verification/wallets/smart-id/ \\\n  --header 'x-api-key: YOUR_API_KEY' \\\n  --header 'Idempotency-Key: your-unique-attempt-key' \\\n  --header 'Content-Type: application/json' \\\n  --data '{\n  \"country\": \"EST\",\n  \"vendor_data\": \"your-customer-reference\",\n  \"metadata\": {\n    \"reference\": \"example\"\n  },\n  \"personal_code\": \"00000000000\"\n}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.id_wallets.start_smart_id(\n    vendor_data=\"your-customer-reference\",\n    metadata={\"reference\": \"example\"},\n    country=\"EST\",\n    personal_code=\"00000000000\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.idWallets.startSmartId({\n  vendor_data: \"your-customer-reference\",\n  metadata: { reference: \"example\" },\n  country: \"EST\",\n  personal_code: \"00000000000\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.IDWallets.StartSmartID(ctx, didit.IDWalletsStartSmartIDParams{\n\tBody: didit.DigitalIDWalletAPISmartIDWalletVerificationStartRequest{\n\t\tVendorData:   didit.String(\"your-customer-reference\"),\n\t\tMetadata:     didit.Some(map[string]any{\"reference\": \"example\"}),\n\t\tCountry:      didit.DigitalIDWalletAPISmartIDWalletVerificationStartCountryEnum(\"EST\"),\n\t\tPersonalCode: \"00000000000\",\n\t},\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.DigitalIdWalletApiSmartIdWalletVerificationStartCountryEnum;\nimport me.didit.types.DigitalIdWalletApiSmartIdWalletVerificationStartRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.idWallets().startSmartId(DigitalIdWalletApiSmartIdWalletVerificationStartRequest.builder()\n        .vendorData(\"your-customer-reference\")\n        .metadata(Map.of(\"reference\", \"example\"))\n        .country(DigitalIdWalletApiSmartIdWalletVerificationStartCountryEnum.of(\"EST\"))\n        .personalCode(\"00000000000\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->idWallets->startSmartId([\n    'vendor_data' => 'your-customer-reference',\n    'metadata' => ['reference' => 'example'],\n    'country' => 'EST',\n    'personal_code' => '00000000000',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.id_wallets.start_smart_id(\n  vendor_data: \"your-customer-reference\",\n  metadata: { reference: \"example\" },\n  country: \"EST\",\n  personal_code: \"00000000000\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.IdWallets.StartSmartIdAsync(new DigitalIdWalletApiSmartIdWalletVerificationStartRequest\n{\n    VendorData = \"your-customer-reference\",\n    Metadata = new Dictionary<string, object> { [\"reference\"] = \"example\" },\n    Country = \"EST\",\n    PersonalCode = \"00000000000\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "x-didit-wallet-id": "smart_id"
      }
    },
    "/v3/id-verification/wallets/mobile-id/": {
      "post": {
        "operationId": "start_mobile_id_wallet_verification",
        "x-didit-sdk": {
          "resource": "id_wallets",
          "method": "start_mobile_id",
          "auth": "api_key",
          "server": true
        },
        "description": "Mulai proses masuk Mobile-ID (SK ID Solutions bersama operator seluler nasional; EST, LTU) tanpa alur kerja apa pun. Ditagih sekali, hanya ketika identitas diverifikasi. Respons membawa next_action.type=confirm_in_app dengan kode perbandingan untuk ditampilkan kepada pengguna; pengguna mengonfirmasinya dan memasukkan PIN mereka di aplikasi (jangan pernah mengumpulkan PIN tersebut). Lakukan polling POST /v3/id-verification/wallets/verifications/{request_id}/poll/ setiap poll_interval_seconds, atau andalkan webhook: Didit juga melakukan polling di latar belakang. Aplikasi sandbox mendapatkan simulasi deterministik (simulated: true) yang tidak pernah menghubungi penyedia.",
        "summary": "Mulai verifikasi Mobile-ID",
        "parameters": [
          {
            "in": "header",
            "name": "Idempotency-Key",
            "schema": {
              "type": "string"
            },
            "description": "Kunci keamanan coba lagi opsional (maks 255 karakter). Mencoba lagi dengan kunci, dompet, dan body yang sama akan mengembalikan verifikasi asli tanpa memulai proses masuk kedua; kunci yang sama dengan dompet atau body lain akan mengembalikan 409 idempotency_key_reused."
          }
        ],
        "tags": [
          "Digital ID wallets"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiMobileIdWalletVerificationStartRequest"
              },
              "example": {
                "country": "EST",
                "vendor_data": "your-customer-reference",
                "metadata": {
                  "reference": "example"
                },
                "personal_code": "00000000000",
                "phone_number": "+37200000000"
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiMobileIdWalletVerificationStartRequest"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiMobileIdWalletVerificationStartRequest"
              }
            }
          },
          "required": true
        },
        "security": [
          {
            "ApiKeyAuth": []
          },
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationResponse"
                },
                "example": {
                  "request_id": "00000000-0000-4000-8000-000000000001",
                  "wallet_verification": {
                    "wallet": {
                      "id": "mobile_id",
                      "name": "Mobile-ID",
                      "issuing_authority": "SK ID Solutions with the national mobile operators"
                    },
                    "country": "EST",
                    "status": "Not Finished",
                    "outcome": "pending",
                    "error": null,
                    "interaction": "in_app",
                    "simulated": true,
                    "expires_at": "2026-01-01T10:10:00Z",
                    "next_action": {
                      "type": "confirm_in_app",
                      "verification_code": "1234",
                      "poll_interval_seconds": 2
                    },
                    "identity": null,
                    "attributes": null,
                    "level_of_assurance": null,
                    "verified_at": null,
                    "signature_valid": null,
                    "credential_type": "person_identification"
                  },
                  "vendor_data": "your-customer-reference",
                  "metadata": {
                    "reference": "example"
                  },
                  "created_at": "2026-01-01T10:00:00Z"
                }
              }
            },
            "description": ""
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationStartBadRequest"
                }
              }
            },
            "description": "Error validasi kolom ({field: [messages]}), atau error return_url_invalid, return_url_not_allowed, invalid_personal_code, invalid_phone_number, atau idempotency_key_invalid."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationStartForbidden"
                }
              }
            },
            "description": "Kredensial tidak ada ({detail}), atau kesalahan wallet_unavailable, insufficient_credits, atau contract_rate_missing."
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "kesalahan idempotency_key_reused atau idempotency_key_in_progress (dengan Retry-After)."
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "kesalahan wallet_provider_unavailable: penyedia tidak dapat memulai; tidak ada yang dibuat."
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "kesalahan wallet_not_configured: lingkungan ini tidak dapat menjangkau dompet."
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL",
            "source": "curl --request POST \\\n  --url https://verification.didit.me/v3/id-verification/wallets/mobile-id/ \\\n  --header 'x-api-key: YOUR_API_KEY' \\\n  --header 'Idempotency-Key: your-unique-attempt-key' \\\n  --header 'Content-Type: application/json' \\\n  --data '{\n  \"country\": \"EST\",\n  \"vendor_data\": \"your-customer-reference\",\n  \"metadata\": {\n    \"reference\": \"example\"\n  },\n  \"personal_code\": \"00000000000\",\n  \"phone_number\": \"+37200000000\"\n}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.id_wallets.start_mobile_id(\n    vendor_data=\"your-customer-reference\",\n    metadata={\"reference\": \"example\"},\n    country=\"EST\",\n    personal_code=\"00000000000\",\n    phone_number=\"+37200000000\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.idWallets.startMobileId({\n  vendor_data: \"your-customer-reference\",\n  metadata: { reference: \"example\" },\n  country: \"EST\",\n  personal_code: \"00000000000\",\n  phone_number: \"+37200000000\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.IDWallets.StartMobileID(ctx, didit.IDWalletsStartMobileIDParams{\n\tBody: didit.DigitalIDWalletAPIMobileIDWalletVerificationStartRequest{\n\t\tVendorData:   didit.String(\"your-customer-reference\"),\n\t\tMetadata:     didit.Some(map[string]any{\"reference\": \"example\"}),\n\t\tCountry:      didit.DigitalIDWalletAPIMobileIDWalletVerificationStartCountryEnum(\"EST\"),\n\t\tPersonalCode: \"00000000000\",\n\t\tPhoneNumber:  \"+37200000000\",\n\t},\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.DigitalIdWalletApiMobileIdWalletVerificationStartCountryEnum;\nimport me.didit.types.DigitalIdWalletApiMobileIdWalletVerificationStartRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.idWallets().startMobileId(DigitalIdWalletApiMobileIdWalletVerificationStartRequest.builder()\n        .vendorData(\"your-customer-reference\")\n        .metadata(Map.of(\"reference\", \"example\"))\n        .country(DigitalIdWalletApiMobileIdWalletVerificationStartCountryEnum.of(\"EST\"))\n        .personalCode(\"00000000000\")\n        .phoneNumber(\"+37200000000\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->idWallets->startMobileId([\n    'vendor_data' => 'your-customer-reference',\n    'metadata' => ['reference' => 'example'],\n    'country' => 'EST',\n    'personal_code' => '00000000000',\n    'phone_number' => '+37200000000',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.id_wallets.start_mobile_id(\n  vendor_data: \"your-customer-reference\",\n  metadata: { reference: \"example\" },\n  country: \"EST\",\n  personal_code: \"00000000000\",\n  phone_number: \"+37200000000\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.IdWallets.StartMobileIdAsync(new DigitalIdWalletApiMobileIdWalletVerificationStartRequest\n{\n    VendorData = \"your-customer-reference\",\n    Metadata = new Dictionary<string, object> { [\"reference\"] = \"example\" },\n    Country = \"EST\",\n    PersonalCode = \"00000000000\",\n    PhoneNumber = \"+37200000000\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "x-didit-wallet-id": "mobile_id"
      }
    },
    "/v3/id-verification/wallets/idcard-ee/": {
      "post": {
        "operationId": "start_idcard_ee_wallet_verification",
        "x-didit-sdk": {
          "resource": "id_wallets",
          "method": "start_idcard_ee",
          "auth": "api_key",
          "server": true
        },
        "description": "Mulai proses masuk Estonian ID-card (Police and Border Guard Board (Estonia); EST) tanpa alur kerja apa pun. Ditagih sekali, hanya ketika identitas terverifikasi. Respons membawa next_action.type=redirect beserta URL untuk mengarahkan browser pengguna; pengguna kembali ke return_url dengan request_id dan result yang dilampirkan. Baca hasilnya dengan GET /v3/id-verification/wallets/verifications/{request_id}/ atau dari webhook, jangan pernah dari URL. Aplikasi sandbox mendapatkan simulasi deterministik (simulated: true) yang tidak pernah menghubungi penyedia.",
        "summary": "Mulai verifikasi Estonian ID-card",
        "parameters": [
          {
            "in": "header",
            "name": "Idempotency-Key",
            "schema": {
              "type": "string"
            },
            "description": "Kunci keamanan coba lagi opsional (maks 255 karakter). Mencoba lagi dengan kunci, dompet, dan body yang sama akan mengembalikan verifikasi asli tanpa memulai proses masuk kedua; kunci yang sama dengan dompet atau body lain akan mengembalikan 409 idempotency_key_reused."
          }
        ],
        "tags": [
          "Digital ID wallets"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiIdcardEeWalletVerificationStartRequest"
              },
              "example": {
                "country": "EST",
                "vendor_data": "your-customer-reference",
                "metadata": {
                  "reference": "example"
                },
                "return_url": "https://app.example.com/identity/complete"
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiIdcardEeWalletVerificationStartRequest"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiIdcardEeWalletVerificationStartRequest"
              }
            }
          },
          "required": true
        },
        "security": [
          {
            "ApiKeyAuth": []
          },
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationResponse"
                },
                "example": {
                  "request_id": "00000000-0000-4000-8000-000000000001",
                  "wallet_verification": {
                    "wallet": {
                      "id": "idcard_ee",
                      "name": "Estonian ID-card",
                      "issuing_authority": "Police and Border Guard Board (Estonia)"
                    },
                    "country": "EST",
                    "status": "Not Finished",
                    "outcome": "pending",
                    "error": null,
                    "interaction": "redirect",
                    "simulated": false,
                    "expires_at": "2026-01-01T10:10:00Z",
                    "next_action": {
                      "type": "redirect",
                      "url": "https://wallet.example.com/authorize"
                    },
                    "identity": null,
                    "attributes": null,
                    "level_of_assurance": null,
                    "verified_at": null,
                    "signature_valid": null,
                    "credential_type": "person_identification"
                  },
                  "vendor_data": "your-customer-reference",
                  "metadata": {
                    "reference": "example"
                  },
                  "created_at": "2026-01-01T10:00:00Z"
                }
              }
            },
            "description": ""
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationStartBadRequest"
                }
              }
            },
            "description": "Error validasi kolom ({field: [messages]}), atau error return_url_invalid, return_url_not_allowed, invalid_personal_code, invalid_phone_number, atau idempotency_key_invalid."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationStartForbidden"
                }
              }
            },
            "description": "Kredensial tidak ada ({detail}), atau kesalahan wallet_unavailable, insufficient_credits, atau contract_rate_missing."
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "kesalahan idempotency_key_reused atau idempotency_key_in_progress (dengan Retry-After)."
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "kesalahan wallet_provider_unavailable: penyedia tidak dapat memulai; tidak ada yang dibuat."
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "kesalahan wallet_not_configured: lingkungan ini tidak dapat menjangkau dompet."
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL",
            "source": "curl --request POST \\\n  --url https://verification.didit.me/v3/id-verification/wallets/idcard-ee/ \\\n  --header 'x-api-key: YOUR_API_KEY' \\\n  --header 'Idempotency-Key: your-unique-attempt-key' \\\n  --header 'Content-Type: application/json' \\\n  --data '{\n  \"country\": \"EST\",\n  \"vendor_data\": \"your-customer-reference\",\n  \"metadata\": {\n    \"reference\": \"example\"\n  },\n  \"return_url\": \"https://app.example.com/identity/complete\"\n}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.id_wallets.start_idcard_ee(\n    vendor_data=\"your-customer-reference\",\n    metadata={\"reference\": \"example\"},\n    country=\"EST\",\n    return_url=\"https://app.example.com/identity/complete\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.idWallets.startIdcardEe({\n  vendor_data: \"your-customer-reference\",\n  metadata: { reference: \"example\" },\n  country: \"EST\",\n  return_url: \"https://app.example.com/identity/complete\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.IDWallets.StartIdcardEe(ctx, didit.IDWalletsStartIdcardEeParams{\n\tBody: didit.DigitalIDWalletAPIIdcardEeWalletVerificationStartRequest{\n\t\tVendorData: didit.String(\"your-customer-reference\"),\n\t\tMetadata:   didit.Some(map[string]any{\"reference\": \"example\"}),\n\t\tCountry:    didit.Some(didit.DigitalIDWalletAPIIdcardEeWalletVerificationStartCountryEnum(\"EST\")),\n\t\tReturnURL:  \"https://app.example.com/identity/complete\",\n\t},\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.DigitalIdWalletApiIdcardEeWalletVerificationStartCountryEnum;\nimport me.didit.types.DigitalIdWalletApiIdcardEeWalletVerificationStartRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.idWallets().startIdcardEe(DigitalIdWalletApiIdcardEeWalletVerificationStartRequest.builder()\n        .vendorData(\"your-customer-reference\")\n        .metadata(Map.of(\"reference\", \"example\"))\n        .country(DigitalIdWalletApiIdcardEeWalletVerificationStartCountryEnum.of(\"EST\"))\n        .returnUrl(\"https://app.example.com/identity/complete\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->idWallets->startIdcardEe([\n    'vendor_data' => 'your-customer-reference',\n    'metadata' => ['reference' => 'example'],\n    'country' => 'EST',\n    'return_url' => 'https://app.example.com/identity/complete',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.id_wallets.start_idcard_ee(\n  vendor_data: \"your-customer-reference\",\n  metadata: { reference: \"example\" },\n  country: \"EST\",\n  return_url: \"https://app.example.com/identity/complete\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.IdWallets.StartIdcardEeAsync(new DigitalIdWalletApiIdcardEeWalletVerificationStartRequest\n{\n    VendorData = \"your-customer-reference\",\n    Metadata = new Dictionary<string, object> { [\"reference\"] = \"example\" },\n    Country = new DigitalIdWalletApiIdcardEeWalletVerificationStartCountryEnum(\"EST\"),\n    ReturnUrl = \"https://app.example.com/identity/complete\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "x-didit-wallet-id": "idcard_ee"
      }
    },
    "/v3/id-verification/wallets/eparaksts-mobile/": {
      "post": {
        "operationId": "start_eparaksts_mobile_wallet_verification",
        "x-didit-sdk": {
          "resource": "id_wallets",
          "method": "start_eparaksts_mobile",
          "auth": "api_key",
          "server": true
        },
        "description": "Mulai proses masuk eParaksts mobile (LVRTC (Latvian State Radio and Television Centre); LVA) tanpa alur kerja apa pun. Ditagih sekali, hanya saat identitas terverifikasi. Respons membawa next_action.type=redirect berisi URL tujuan pengalihan browser pengguna; pengguna kembali ke return_url dengan request_id dan result yang ditambahkan. Baca hasilnya dengan GET /v3/id-verification/wallets/verifications/{request_id}/ atau dari webhook, jangan pernah dari URL. Aplikasi sandbox mendapatkan simulasi deterministik (simulated: true) yang tidak pernah menghubungi penyedia.",
        "summary": "Mulai verifikasi seluler eParaksts",
        "parameters": [
          {
            "in": "header",
            "name": "Idempotency-Key",
            "schema": {
              "type": "string"
            },
            "description": "Kunci keamanan coba lagi opsional (maks 255 karakter). Mencoba lagi dengan kunci, dompet, dan body yang sama akan mengembalikan verifikasi asli tanpa memulai proses masuk kedua; kunci yang sama dengan dompet atau body lain akan mengembalikan 409 idempotency_key_reused."
          }
        ],
        "tags": [
          "Digital ID wallets"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiEparakstsMobileWalletVerificationStartRequest"
              },
              "example": {
                "country": "LVA",
                "vendor_data": "your-customer-reference",
                "metadata": {
                  "reference": "example"
                },
                "return_url": "https://app.example.com/identity/complete"
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiEparakstsMobileWalletVerificationStartRequest"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiEparakstsMobileWalletVerificationStartRequest"
              }
            }
          },
          "required": true
        },
        "security": [
          {
            "ApiKeyAuth": []
          },
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationResponse"
                },
                "example": {
                  "request_id": "00000000-0000-4000-8000-000000000001",
                  "wallet_verification": {
                    "wallet": {
                      "id": "eparaksts_mobile",
                      "name": "eParaksts mobile",
                      "issuing_authority": "LVRTC (Latvian State Radio and Television Centre)"
                    },
                    "country": "LVA",
                    "status": "Not Finished",
                    "outcome": "pending",
                    "error": null,
                    "interaction": "redirect",
                    "simulated": false,
                    "expires_at": "2026-01-01T10:10:00Z",
                    "next_action": {
                      "type": "redirect",
                      "url": "https://wallet.example.com/authorize"
                    },
                    "identity": null,
                    "attributes": null,
                    "level_of_assurance": null,
                    "verified_at": null,
                    "signature_valid": null,
                    "credential_type": "person_identification"
                  },
                  "vendor_data": "your-customer-reference",
                  "metadata": {
                    "reference": "example"
                  },
                  "created_at": "2026-01-01T10:00:00Z"
                }
              }
            },
            "description": ""
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationStartBadRequest"
                }
              }
            },
            "description": "Error validasi kolom ({field: [messages]}), atau error return_url_invalid, return_url_not_allowed, invalid_personal_code, invalid_phone_number, atau idempotency_key_invalid."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationStartForbidden"
                }
              }
            },
            "description": "Kredensial tidak ada ({detail}), atau kesalahan wallet_unavailable, insufficient_credits, atau contract_rate_missing."
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "kesalahan idempotency_key_reused atau idempotency_key_in_progress (dengan Retry-After)."
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "kesalahan wallet_provider_unavailable: penyedia tidak dapat memulai; tidak ada yang dibuat."
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "kesalahan wallet_not_configured: lingkungan ini tidak dapat menjangkau dompet."
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL",
            "source": "curl --request POST \\\n  --url https://verification.didit.me/v3/id-verification/wallets/eparaksts-mobile/ \\\n  --header 'x-api-key: YOUR_API_KEY' \\\n  --header 'Idempotency-Key: your-unique-attempt-key' \\\n  --header 'Content-Type: application/json' \\\n  --data '{\n  \"country\": \"LVA\",\n  \"vendor_data\": \"your-customer-reference\",\n  \"metadata\": {\n    \"reference\": \"example\"\n  },\n  \"return_url\": \"https://app.example.com/identity/complete\"\n}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.id_wallets.start_eparaksts_mobile(\n    vendor_data=\"your-customer-reference\",\n    metadata={\"reference\": \"example\"},\n    country=\"LVA\",\n    return_url=\"https://app.example.com/identity/complete\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.idWallets.startEparakstsMobile({\n  vendor_data: \"your-customer-reference\",\n  metadata: { reference: \"example\" },\n  country: \"LVA\",\n  return_url: \"https://app.example.com/identity/complete\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.IDWallets.StartEparakstsMobile(ctx, didit.IDWalletsStartEparakstsMobileParams{\n\tBody: didit.DigitalIDWalletAPIEparakstsMobileWalletVerificationStartRequest{\n\t\tVendorData: didit.String(\"your-customer-reference\"),\n\t\tMetadata:   didit.Some(map[string]any{\"reference\": \"example\"}),\n\t\tCountry:    didit.Some(didit.DigitalIDWalletAPIEparakstsMobileWalletVerificationStartCountryEnum(\"LVA\")),\n\t\tReturnURL:  \"https://app.example.com/identity/complete\",\n\t},\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.DigitalIdWalletApiEparakstsMobileWalletVerificationStartCountryEnum;\nimport me.didit.types.DigitalIdWalletApiEparakstsMobileWalletVerificationStartRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.idWallets().startEparakstsMobile(DigitalIdWalletApiEparakstsMobileWalletVerificationStartRequest.builder()\n        .vendorData(\"your-customer-reference\")\n        .metadata(Map.of(\"reference\", \"example\"))\n        .country(DigitalIdWalletApiEparakstsMobileWalletVerificationStartCountryEnum.of(\"LVA\"))\n        .returnUrl(\"https://app.example.com/identity/complete\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->idWallets->startEparakstsMobile([\n    'vendor_data' => 'your-customer-reference',\n    'metadata' => ['reference' => 'example'],\n    'country' => 'LVA',\n    'return_url' => 'https://app.example.com/identity/complete',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.id_wallets.start_eparaksts_mobile(\n  vendor_data: \"your-customer-reference\",\n  metadata: { reference: \"example\" },\n  country: \"LVA\",\n  return_url: \"https://app.example.com/identity/complete\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.IdWallets.StartEparakstsMobileAsync(new DigitalIdWalletApiEparakstsMobileWalletVerificationStartRequest\n{\n    VendorData = \"your-customer-reference\",\n    Metadata = new Dictionary<string, object> { [\"reference\"] = \"example\" },\n    Country = new DigitalIdWalletApiEparakstsMobileWalletVerificationStartCountryEnum(\"LVA\"),\n    ReturnUrl = \"https://app.example.com/identity/complete\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "x-didit-wallet-id": "eparaksts_mobile"
      }
    },
    "/v3/id-verification/wallets/bankid-cz/": {
      "post": {
        "operationId": "start_bankid_cz_wallet_verification",
        "x-didit-sdk": {
          "resource": "id_wallets",
          "method": "start_bankid_cz",
          "auth": "api_key",
          "server": true
        },
        "description": "Mulai proses masuk Bank iD (Bankovní identita, a.s.; CZE) tanpa alur kerja apa pun. Ditagih sekali, hanya saat identitas terverifikasi. Respons membawa next_action.type=redirect beserta URL tujuan peramban pengguna; pengguna kembali ke return_url dengan request_id dan result yang dilampirkan. Baca hasilnya dengan GET /v3/id-verification/wallets/verifications/{request_id}/ atau dari webhook, jangan pernah dari URL. Aplikasi sandbox mendapatkan simulasi deterministik (simulated: true) yang tidak pernah menghubungi penyedia.",
        "summary": "Mulai verifikasi Bank iD",
        "parameters": [
          {
            "in": "header",
            "name": "Idempotency-Key",
            "schema": {
              "type": "string"
            },
            "description": "Kunci keamanan coba lagi opsional (maks 255 karakter). Mencoba lagi dengan kunci, dompet, dan body yang sama akan mengembalikan verifikasi asli tanpa memulai proses masuk kedua; kunci yang sama dengan dompet atau body lain akan mengembalikan 409 idempotency_key_reused."
          }
        ],
        "tags": [
          "Digital ID wallets"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiBankidCzWalletVerificationStartRequest"
              },
              "example": {
                "country": "CZE",
                "vendor_data": "your-customer-reference",
                "metadata": {
                  "reference": "example"
                },
                "return_url": "https://app.example.com/identity/complete"
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiBankidCzWalletVerificationStartRequest"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiBankidCzWalletVerificationStartRequest"
              }
            }
          },
          "required": true
        },
        "security": [
          {
            "ApiKeyAuth": []
          },
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationResponse"
                },
                "example": {
                  "request_id": "00000000-0000-4000-8000-000000000001",
                  "wallet_verification": {
                    "wallet": {
                      "id": "bankid_cz",
                      "name": "Bank iD",
                      "issuing_authority": "Bankovní identita, a.s."
                    },
                    "country": "CZE",
                    "status": "Not Finished",
                    "outcome": "pending",
                    "error": null,
                    "interaction": "redirect",
                    "simulated": false,
                    "expires_at": "2026-01-01T10:10:00Z",
                    "next_action": {
                      "type": "redirect",
                      "url": "https://wallet.example.com/authorize"
                    },
                    "identity": null,
                    "attributes": null,
                    "level_of_assurance": null,
                    "verified_at": null,
                    "signature_valid": null,
                    "credential_type": "person_identification"
                  },
                  "vendor_data": "your-customer-reference",
                  "metadata": {
                    "reference": "example"
                  },
                  "created_at": "2026-01-01T10:00:00Z"
                }
              }
            },
            "description": ""
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationStartBadRequest"
                }
              }
            },
            "description": "Error validasi kolom ({field: [messages]}), atau error return_url_invalid, return_url_not_allowed, invalid_personal_code, invalid_phone_number, atau idempotency_key_invalid."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationStartForbidden"
                }
              }
            },
            "description": "Kredensial tidak ada ({detail}), atau kesalahan wallet_unavailable, insufficient_credits, atau contract_rate_missing."
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "kesalahan idempotency_key_reused atau idempotency_key_in_progress (dengan Retry-After)."
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "kesalahan wallet_provider_unavailable: penyedia tidak dapat memulai; tidak ada yang dibuat."
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "kesalahan wallet_not_configured: lingkungan ini tidak dapat menjangkau dompet."
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL",
            "source": "curl --request POST \\\n  --url https://verification.didit.me/v3/id-verification/wallets/bankid-cz/ \\\n  --header 'x-api-key: YOUR_API_KEY' \\\n  --header 'Idempotency-Key: your-unique-attempt-key' \\\n  --header 'Content-Type: application/json' \\\n  --data '{\n  \"country\": \"CZE\",\n  \"vendor_data\": \"your-customer-reference\",\n  \"metadata\": {\n    \"reference\": \"example\"\n  },\n  \"return_url\": \"https://app.example.com/identity/complete\"\n}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.id_wallets.start_bankid_cz(\n    vendor_data=\"your-customer-reference\",\n    metadata={\"reference\": \"example\"},\n    country=\"CZE\",\n    return_url=\"https://app.example.com/identity/complete\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.idWallets.startBankidCz({\n  vendor_data: \"your-customer-reference\",\n  metadata: { reference: \"example\" },\n  country: \"CZE\",\n  return_url: \"https://app.example.com/identity/complete\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.IDWallets.StartBankidCz(ctx, didit.IDWalletsStartBankidCzParams{\n\tBody: didit.DigitalIDWalletAPIBankidCzWalletVerificationStartRequest{\n\t\tVendorData: didit.String(\"your-customer-reference\"),\n\t\tMetadata:   didit.Some(map[string]any{\"reference\": \"example\"}),\n\t\tCountry:    didit.Some(didit.DigitalIDWalletAPICountryE2dEnum(\"CZE\")),\n\t\tReturnURL:  \"https://app.example.com/identity/complete\",\n\t},\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.DigitalIdWalletApiBankidCzWalletVerificationStartRequest;\nimport me.didit.types.DigitalIdWalletApiCountryE2dEnum;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.idWallets().startBankidCz(DigitalIdWalletApiBankidCzWalletVerificationStartRequest.builder()\n        .vendorData(\"your-customer-reference\")\n        .metadata(Map.of(\"reference\", \"example\"))\n        .country(DigitalIdWalletApiCountryE2dEnum.of(\"CZE\"))\n        .returnUrl(\"https://app.example.com/identity/complete\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->idWallets->startBankidCz([\n    'vendor_data' => 'your-customer-reference',\n    'metadata' => ['reference' => 'example'],\n    'country' => 'CZE',\n    'return_url' => 'https://app.example.com/identity/complete',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.id_wallets.start_bankid_cz(\n  vendor_data: \"your-customer-reference\",\n  metadata: { reference: \"example\" },\n  country: \"CZE\",\n  return_url: \"https://app.example.com/identity/complete\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.IdWallets.StartBankidCzAsync(new DigitalIdWalletApiBankidCzWalletVerificationStartRequest\n{\n    VendorData = \"your-customer-reference\",\n    Metadata = new Dictionary<string, object> { [\"reference\"] = \"example\" },\n    Country = new DigitalIdWalletApiCountryE2dEnum(\"CZE\"),\n    ReturnUrl = \"https://app.example.com/identity/complete\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "x-didit-wallet-id": "bankid_cz"
      }
    },
    "/v3/id-verification/wallets/mojeid/": {
      "post": {
        "operationId": "start_mojeid_wallet_verification",
        "x-didit-sdk": {
          "resource": "id_wallets",
          "method": "start_mojeid",
          "auth": "api_key",
          "server": true
        },
        "description": "Mulai proses masuk MojeID (CZ.NIC; CZE) tanpa alur kerja apa pun. Ditagih sekali, hanya saat identitas terverifikasi. Respons membawa next_action.type=redirect berisi URL tujuan pengalihan browser pengguna; pengguna kembali ke return_url dengan request_id dan result yang ditambahkan. Baca hasilnya dengan GET /v3/id-verification/wallets/verifications/{request_id}/ atau dari webhook, jangan pernah dari URL. Aplikasi sandbox mendapatkan simulasi deterministik (simulated: true) yang tidak pernah menghubungi penyedia.",
        "summary": "Mulai verifikasi MojeID",
        "parameters": [
          {
            "in": "header",
            "name": "Idempotency-Key",
            "schema": {
              "type": "string"
            },
            "description": "Kunci keamanan coba lagi opsional (maks 255 karakter). Mencoba lagi dengan kunci, dompet, dan body yang sama akan mengembalikan verifikasi asli tanpa memulai proses masuk kedua; kunci yang sama dengan dompet atau body lain akan mengembalikan 409 idempotency_key_reused."
          }
        ],
        "tags": [
          "Digital ID wallets"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiMojeidWalletVerificationStartRequest"
              },
              "example": {
                "country": "CZE",
                "vendor_data": "your-customer-reference",
                "metadata": {
                  "reference": "example"
                },
                "return_url": "https://app.example.com/identity/complete"
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiMojeidWalletVerificationStartRequest"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiMojeidWalletVerificationStartRequest"
              }
            }
          },
          "required": true
        },
        "security": [
          {
            "ApiKeyAuth": []
          },
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationResponse"
                },
                "example": {
                  "request_id": "00000000-0000-4000-8000-000000000001",
                  "wallet_verification": {
                    "wallet": {
                      "id": "mojeid",
                      "name": "MojeID",
                      "issuing_authority": "CZ.NIC"
                    },
                    "country": "CZE",
                    "status": "Not Finished",
                    "outcome": "pending",
                    "error": null,
                    "interaction": "redirect",
                    "simulated": false,
                    "expires_at": "2026-01-01T10:10:00Z",
                    "next_action": {
                      "type": "redirect",
                      "url": "https://wallet.example.com/authorize"
                    },
                    "identity": null,
                    "attributes": null,
                    "level_of_assurance": null,
                    "verified_at": null,
                    "signature_valid": null,
                    "credential_type": "person_identification"
                  },
                  "vendor_data": "your-customer-reference",
                  "metadata": {
                    "reference": "example"
                  },
                  "created_at": "2026-01-01T10:00:00Z"
                }
              }
            },
            "description": ""
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationStartBadRequest"
                }
              }
            },
            "description": "Error validasi kolom ({field: [messages]}), atau error return_url_invalid, return_url_not_allowed, invalid_personal_code, invalid_phone_number, atau idempotency_key_invalid."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationStartForbidden"
                }
              }
            },
            "description": "Kredensial tidak ada ({detail}), atau kesalahan wallet_unavailable, insufficient_credits, atau contract_rate_missing."
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "kesalahan idempotency_key_reused atau idempotency_key_in_progress (dengan Retry-After)."
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "kesalahan wallet_provider_unavailable: penyedia tidak dapat memulai; tidak ada yang dibuat."
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "kesalahan wallet_not_configured: lingkungan ini tidak dapat menjangkau dompet."
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL",
            "source": "curl --request POST \\\n  --url https://verification.didit.me/v3/id-verification/wallets/mojeid/ \\\n  --header 'x-api-key: YOUR_API_KEY' \\\n  --header 'Idempotency-Key: your-unique-attempt-key' \\\n  --header 'Content-Type: application/json' \\\n  --data '{\n  \"country\": \"CZE\",\n  \"vendor_data\": \"your-customer-reference\",\n  \"metadata\": {\n    \"reference\": \"example\"\n  },\n  \"return_url\": \"https://app.example.com/identity/complete\"\n}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.id_wallets.start_mojeid(\n    vendor_data=\"your-customer-reference\",\n    metadata={\"reference\": \"example\"},\n    country=\"CZE\",\n    return_url=\"https://app.example.com/identity/complete\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.idWallets.startMojeid({\n  vendor_data: \"your-customer-reference\",\n  metadata: { reference: \"example\" },\n  country: \"CZE\",\n  return_url: \"https://app.example.com/identity/complete\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.IDWallets.StartMojeid(ctx, didit.IDWalletsStartMojeidParams{\n\tBody: didit.DigitalIDWalletAPIMojeidWalletVerificationStartRequest{\n\t\tVendorData: didit.String(\"your-customer-reference\"),\n\t\tMetadata:   didit.Some(map[string]any{\"reference\": \"example\"}),\n\t\tCountry:    didit.Some(didit.DigitalIDWalletAPICountryE2dEnum(\"CZE\")),\n\t\tReturnURL:  \"https://app.example.com/identity/complete\",\n\t},\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.DigitalIdWalletApiCountryE2dEnum;\nimport me.didit.types.DigitalIdWalletApiMojeidWalletVerificationStartRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.idWallets().startMojeid(DigitalIdWalletApiMojeidWalletVerificationStartRequest.builder()\n        .vendorData(\"your-customer-reference\")\n        .metadata(Map.of(\"reference\", \"example\"))\n        .country(DigitalIdWalletApiCountryE2dEnum.of(\"CZE\"))\n        .returnUrl(\"https://app.example.com/identity/complete\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->idWallets->startMojeid([\n    'vendor_data' => 'your-customer-reference',\n    'metadata' => ['reference' => 'example'],\n    'country' => 'CZE',\n    'return_url' => 'https://app.example.com/identity/complete',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.id_wallets.start_mojeid(\n  vendor_data: \"your-customer-reference\",\n  metadata: { reference: \"example\" },\n  country: \"CZE\",\n  return_url: \"https://app.example.com/identity/complete\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.IdWallets.StartMojeidAsync(new DigitalIdWalletApiMojeidWalletVerificationStartRequest\n{\n    VendorData = \"your-customer-reference\",\n    Metadata = new Dictionary<string, object> { [\"reference\"] = \"example\" },\n    Country = new DigitalIdWalletApiCountryE2dEnum(\"CZE\"),\n    ReturnUrl = \"https://app.example.com/identity/complete\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "x-didit-wallet-id": "mojeid"
      }
    },
    "/v3/id-verification/wallets/diia/": {
      "post": {
        "operationId": "start_diia_wallet_verification",
        "x-didit-sdk": {
          "resource": "id_wallets",
          "method": "start_diia",
          "auth": "api_key",
          "server": true
        },
        "description": "Mulai proses masuk Diia (Ministry of Digital Transformation of Ukraine; UKR) tanpa alur kerja apa pun. Ditagih sekali, hanya ketika identitas terverifikasi. Respons membawa next_action.type=redirect beserta URL untuk mengarahkan browser pengguna; pengguna kembali ke return_url dengan request_id dan result yang dilampirkan. Baca hasilnya dengan GET /v3/id-verification/wallets/verifications/{request_id}/ atau dari webhook, jangan pernah dari URL. Aplikasi sandbox mendapatkan simulasi deterministik (simulated: true) yang tidak pernah menghubungi penyedia.",
        "summary": "Mulai verifikasi Diia",
        "parameters": [
          {
            "in": "header",
            "name": "Idempotency-Key",
            "schema": {
              "type": "string"
            },
            "description": "Kunci keamanan coba lagi opsional (maks 255 karakter). Mencoba lagi dengan kunci, dompet, dan body yang sama akan mengembalikan verifikasi asli tanpa memulai proses masuk kedua; kunci yang sama dengan dompet atau body lain akan mengembalikan 409 idempotency_key_reused."
          }
        ],
        "tags": [
          "Digital ID wallets"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiDiiaWalletVerificationStartRequest"
              },
              "example": {
                "country": "UKR",
                "vendor_data": "your-customer-reference",
                "metadata": {
                  "reference": "example"
                },
                "return_url": "https://app.example.com/identity/complete"
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiDiiaWalletVerificationStartRequest"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiDiiaWalletVerificationStartRequest"
              }
            }
          },
          "required": true
        },
        "security": [
          {
            "ApiKeyAuth": []
          },
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationResponse"
                },
                "example": {
                  "request_id": "00000000-0000-4000-8000-000000000001",
                  "wallet_verification": {
                    "wallet": {
                      "id": "diia",
                      "name": "Diia",
                      "issuing_authority": "Ministry of Digital Transformation of Ukraine"
                    },
                    "country": "UKR",
                    "status": "Not Finished",
                    "outcome": "pending",
                    "error": null,
                    "interaction": "redirect",
                    "simulated": false,
                    "expires_at": "2026-01-01T10:10:00Z",
                    "next_action": {
                      "type": "redirect",
                      "url": "https://wallet.example.com/authorize"
                    },
                    "identity": null,
                    "attributes": null,
                    "level_of_assurance": null,
                    "verified_at": null,
                    "signature_valid": null,
                    "credential_type": "person_identification"
                  },
                  "vendor_data": "your-customer-reference",
                  "metadata": {
                    "reference": "example"
                  },
                  "created_at": "2026-01-01T10:00:00Z"
                }
              }
            },
            "description": ""
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationStartBadRequest"
                }
              }
            },
            "description": "Error validasi kolom ({field: [messages]}), atau error return_url_invalid, return_url_not_allowed, invalid_personal_code, invalid_phone_number, atau idempotency_key_invalid."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationStartForbidden"
                }
              }
            },
            "description": "Kredensial tidak ada ({detail}), atau kesalahan wallet_unavailable, insufficient_credits, atau contract_rate_missing."
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "kesalahan idempotency_key_reused atau idempotency_key_in_progress (dengan Retry-After)."
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "kesalahan wallet_provider_unavailable: penyedia tidak dapat memulai; tidak ada yang dibuat."
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "kesalahan wallet_not_configured: lingkungan ini tidak dapat menjangkau dompet."
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL",
            "source": "curl --request POST \\\n  --url https://verification.didit.me/v3/id-verification/wallets/diia/ \\\n  --header 'x-api-key: YOUR_API_KEY' \\\n  --header 'Idempotency-Key: your-unique-attempt-key' \\\n  --header 'Content-Type: application/json' \\\n  --data '{\n  \"country\": \"UKR\",\n  \"vendor_data\": \"your-customer-reference\",\n  \"metadata\": {\n    \"reference\": \"example\"\n  },\n  \"return_url\": \"https://app.example.com/identity/complete\"\n}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.id_wallets.start_diia(\n    vendor_data=\"your-customer-reference\",\n    metadata={\"reference\": \"example\"},\n    country=\"UKR\",\n    return_url=\"https://app.example.com/identity/complete\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.idWallets.startDiia({\n  vendor_data: \"your-customer-reference\",\n  metadata: { reference: \"example\" },\n  country: \"UKR\",\n  return_url: \"https://app.example.com/identity/complete\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.IDWallets.StartDiia(ctx, didit.IDWalletsStartDiiaParams{\n\tBody: didit.DigitalIDWalletAPIDiiaWalletVerificationStartRequest{\n\t\tVendorData: didit.String(\"your-customer-reference\"),\n\t\tMetadata:   didit.Some(map[string]any{\"reference\": \"example\"}),\n\t\tCountry:    didit.Some(didit.DigitalIDWalletAPIDiiaWalletVerificationStartCountryEnum(\"UKR\")),\n\t\tReturnURL:  \"https://app.example.com/identity/complete\",\n\t},\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.DigitalIdWalletApiDiiaWalletVerificationStartCountryEnum;\nimport me.didit.types.DigitalIdWalletApiDiiaWalletVerificationStartRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.idWallets().startDiia(DigitalIdWalletApiDiiaWalletVerificationStartRequest.builder()\n        .vendorData(\"your-customer-reference\")\n        .metadata(Map.of(\"reference\", \"example\"))\n        .country(DigitalIdWalletApiDiiaWalletVerificationStartCountryEnum.of(\"UKR\"))\n        .returnUrl(\"https://app.example.com/identity/complete\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->idWallets->startDiia([\n    'vendor_data' => 'your-customer-reference',\n    'metadata' => ['reference' => 'example'],\n    'country' => 'UKR',\n    'return_url' => 'https://app.example.com/identity/complete',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.id_wallets.start_diia(\n  vendor_data: \"your-customer-reference\",\n  metadata: { reference: \"example\" },\n  country: \"UKR\",\n  return_url: \"https://app.example.com/identity/complete\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.IdWallets.StartDiiaAsync(new DigitalIdWalletApiDiiaWalletVerificationStartRequest\n{\n    VendorData = \"your-customer-reference\",\n    Metadata = new Dictionary<string, object> { [\"reference\"] = \"example\" },\n    Country = new DigitalIdWalletApiDiiaWalletVerificationStartCountryEnum(\"UKR\"),\n    ReturnUrl = \"https://app.example.com/identity/complete\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "x-didit-wallet-id": "diia"
      }
    },
    "/v3/id-verification/wallets/franceconnect/": {
      "post": {
        "operationId": "start_franceconnect_wallet_verification",
        "x-didit-sdk": {
          "resource": "id_wallets",
          "method": "start_franceconnect",
          "auth": "api_key",
          "server": true
        },
        "description": "Mulai proses masuk FranceConnect (DINUM (negara Prancis); FRA) tanpa alur kerja apa pun. Ditagih sekali, hanya ketika identitas diverifikasi. Respons membawa next_action.type=redirect dengan URL tujuan browser pengguna; pengguna kembali ke return_url dengan request_id dan result yang ditambahkan. Baca hasilnya dengan GET /v3/id-verification/wallets/verifications/{request_id}/ atau dari webhook, jangan pernah dari URL. Aplikasi sandbox mendapatkan simulasi deterministik (simulated: true) yang tidak pernah menghubungi penyedia.",
        "summary": "Mulai verifikasi FranceConnect",
        "parameters": [
          {
            "in": "header",
            "name": "Idempotency-Key",
            "schema": {
              "type": "string"
            },
            "description": "Kunci keamanan coba lagi opsional (maks 255 karakter). Mencoba lagi dengan kunci, dompet, dan body yang sama akan mengembalikan verifikasi asli tanpa memulai proses masuk kedua; kunci yang sama dengan dompet atau body lain akan mengembalikan 409 idempotency_key_reused."
          }
        ],
        "tags": [
          "Digital ID wallets"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiFranceconnectWalletVerificationStartRequest"
              },
              "example": {
                "country": "FRA",
                "vendor_data": "your-customer-reference",
                "metadata": {
                  "reference": "example"
                },
                "return_url": "https://app.example.com/identity/complete"
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiFranceconnectWalletVerificationStartRequest"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiFranceconnectWalletVerificationStartRequest"
              }
            }
          },
          "required": true
        },
        "security": [
          {
            "ApiKeyAuth": []
          },
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationResponse"
                },
                "example": {
                  "request_id": "00000000-0000-4000-8000-000000000001",
                  "wallet_verification": {
                    "wallet": {
                      "id": "franceconnect",
                      "name": "FranceConnect",
                      "issuing_authority": "DINUM (French state)"
                    },
                    "country": "FRA",
                    "status": "Not Finished",
                    "outcome": "pending",
                    "error": null,
                    "interaction": "redirect",
                    "simulated": false,
                    "expires_at": "2026-01-01T10:10:00Z",
                    "next_action": {
                      "type": "redirect",
                      "url": "https://wallet.example.com/authorize"
                    },
                    "identity": null,
                    "attributes": null,
                    "level_of_assurance": null,
                    "verified_at": null,
                    "signature_valid": null,
                    "credential_type": "person_identification"
                  },
                  "vendor_data": "your-customer-reference",
                  "metadata": {
                    "reference": "example"
                  },
                  "created_at": "2026-01-01T10:00:00Z"
                }
              }
            },
            "description": ""
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationStartBadRequest"
                }
              }
            },
            "description": "Error validasi kolom ({field: [messages]}), atau error return_url_invalid, return_url_not_allowed, invalid_personal_code, invalid_phone_number, atau idempotency_key_invalid."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationStartForbidden"
                }
              }
            },
            "description": "Kredensial tidak ada ({detail}), atau kesalahan wallet_unavailable, insufficient_credits, atau contract_rate_missing."
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "kesalahan idempotency_key_reused atau idempotency_key_in_progress (dengan Retry-After)."
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "kesalahan wallet_provider_unavailable: penyedia tidak dapat memulai; tidak ada yang dibuat."
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "kesalahan wallet_not_configured: lingkungan ini tidak dapat menjangkau dompet."
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL",
            "source": "curl --request POST \\\n  --url https://verification.didit.me/v3/id-verification/wallets/franceconnect/ \\\n  --header 'x-api-key: YOUR_API_KEY' \\\n  --header 'Idempotency-Key: your-unique-attempt-key' \\\n  --header 'Content-Type: application/json' \\\n  --data '{\n  \"country\": \"FRA\",\n  \"vendor_data\": \"your-customer-reference\",\n  \"metadata\": {\n    \"reference\": \"example\"\n  },\n  \"return_url\": \"https://app.example.com/identity/complete\"\n}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.id_wallets.start_franceconnect(\n    vendor_data=\"your-customer-reference\",\n    metadata={\"reference\": \"example\"},\n    country=\"FRA\",\n    return_url=\"https://app.example.com/identity/complete\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.idWallets.startFranceconnect({\n  vendor_data: \"your-customer-reference\",\n  metadata: { reference: \"example\" },\n  country: \"FRA\",\n  return_url: \"https://app.example.com/identity/complete\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.IDWallets.StartFranceconnect(ctx, didit.IDWalletsStartFranceconnectParams{\n\tBody: didit.DigitalIDWalletAPIFranceconnectWalletVerificationStartRequest{\n\t\tVendorData: didit.String(\"your-customer-reference\"),\n\t\tMetadata:   didit.Some(map[string]any{\"reference\": \"example\"}),\n\t\tCountry:    didit.Some(didit.DigitalIDWalletAPIFranceconnectWalletVerificationStartCountryEnum(\"FRA\")),\n\t\tReturnURL:  \"https://app.example.com/identity/complete\",\n\t},\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.DigitalIdWalletApiFranceconnectWalletVerificationStartCountryEnum;\nimport me.didit.types.DigitalIdWalletApiFranceconnectWalletVerificationStartRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.idWallets().startFranceconnect(DigitalIdWalletApiFranceconnectWalletVerificationStartRequest.builder()\n        .vendorData(\"your-customer-reference\")\n        .metadata(Map.of(\"reference\", \"example\"))\n        .country(DigitalIdWalletApiFranceconnectWalletVerificationStartCountryEnum.of(\"FRA\"))\n        .returnUrl(\"https://app.example.com/identity/complete\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->idWallets->startFranceconnect([\n    'vendor_data' => 'your-customer-reference',\n    'metadata' => ['reference' => 'example'],\n    'country' => 'FRA',\n    'return_url' => 'https://app.example.com/identity/complete',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.id_wallets.start_franceconnect(\n  vendor_data: \"your-customer-reference\",\n  metadata: { reference: \"example\" },\n  country: \"FRA\",\n  return_url: \"https://app.example.com/identity/complete\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.IdWallets.StartFranceconnectAsync(new DigitalIdWalletApiFranceconnectWalletVerificationStartRequest\n{\n    VendorData = \"your-customer-reference\",\n    Metadata = new Dictionary<string, object> { [\"reference\"] = \"example\" },\n    Country = new DigitalIdWalletApiFranceconnectWalletVerificationStartCountryEnum(\"FRA\"),\n    ReturnUrl = \"https://app.example.com/identity/complete\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "x-didit-wallet-id": "franceconnect"
      }
    },
    "/v3/id-verification/wallets/audkenni/": {
      "post": {
        "operationId": "start_audkenni_wallet_verification",
        "x-didit-sdk": {
          "resource": "id_wallets",
          "method": "start_audkenni",
          "auth": "api_key",
          "server": true
        },
        "description": "Mulai proses masuk Auðkenni (Auðkenni (ID elektronik Islandia); ISL) tanpa alur kerja apa pun. Ditagih sekali, hanya saat identitas terverifikasi. Respons membawa next_action.type=redirect beserta URL untuk mengarahkan peramban pengguna; pengguna kembali ke return_url dengan request_id dan result yang dilampirkan. Baca hasilnya dengan GET /v3/id-verification/wallets/verifications/{request_id}/ atau dari webhook, jangan pernah dari URL. Aplikasi sandbox mendapatkan simulasi deterministik (simulated: true) yang tidak pernah menghubungi penyedia.",
        "summary": "Mulai verifikasi Auðkenni",
        "parameters": [
          {
            "in": "header",
            "name": "Idempotency-Key",
            "schema": {
              "type": "string"
            },
            "description": "Kunci keamanan coba lagi opsional (maks 255 karakter). Mencoba lagi dengan kunci, dompet, dan body yang sama akan mengembalikan verifikasi asli tanpa memulai proses masuk kedua; kunci yang sama dengan dompet atau body lain akan mengembalikan 409 idempotency_key_reused."
          }
        ],
        "tags": [
          "Digital ID wallets"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiAudkenniWalletVerificationStartRequest"
              },
              "example": {
                "country": "ISL",
                "vendor_data": "your-customer-reference",
                "metadata": {
                  "reference": "example"
                },
                "return_url": "https://app.example.com/identity/complete"
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiAudkenniWalletVerificationStartRequest"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiAudkenniWalletVerificationStartRequest"
              }
            }
          },
          "required": true
        },
        "security": [
          {
            "ApiKeyAuth": []
          },
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationResponse"
                },
                "example": {
                  "request_id": "00000000-0000-4000-8000-000000000001",
                  "wallet_verification": {
                    "wallet": {
                      "id": "audkenni",
                      "name": "Auðkenni",
                      "issuing_authority": "Auðkenni (Icelandic electronic ID)"
                    },
                    "country": "ISL",
                    "status": "Not Finished",
                    "outcome": "pending",
                    "error": null,
                    "interaction": "redirect",
                    "simulated": false,
                    "expires_at": "2026-01-01T10:10:00Z",
                    "next_action": {
                      "type": "redirect",
                      "url": "https://wallet.example.com/authorize"
                    },
                    "identity": null,
                    "attributes": null,
                    "level_of_assurance": null,
                    "verified_at": null,
                    "signature_valid": null,
                    "credential_type": "person_identification"
                  },
                  "vendor_data": "your-customer-reference",
                  "metadata": {
                    "reference": "example"
                  },
                  "created_at": "2026-01-01T10:00:00Z"
                }
              }
            },
            "description": ""
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationStartBadRequest"
                }
              }
            },
            "description": "Error validasi kolom ({field: [messages]}), atau error return_url_invalid, return_url_not_allowed, invalid_personal_code, invalid_phone_number, atau idempotency_key_invalid."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationStartForbidden"
                }
              }
            },
            "description": "Kredensial tidak ada ({detail}), atau kesalahan wallet_unavailable, insufficient_credits, atau contract_rate_missing."
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "kesalahan idempotency_key_reused atau idempotency_key_in_progress (dengan Retry-After)."
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "kesalahan wallet_provider_unavailable: penyedia tidak dapat memulai; tidak ada yang dibuat."
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "kesalahan wallet_not_configured: lingkungan ini tidak dapat menjangkau dompet."
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL",
            "source": "curl --request POST \\\n  --url https://verification.didit.me/v3/id-verification/wallets/audkenni/ \\\n  --header 'x-api-key: YOUR_API_KEY' \\\n  --header 'Idempotency-Key: your-unique-attempt-key' \\\n  --header 'Content-Type: application/json' \\\n  --data '{\n  \"country\": \"ISL\",\n  \"vendor_data\": \"your-customer-reference\",\n  \"metadata\": {\n    \"reference\": \"example\"\n  },\n  \"return_url\": \"https://app.example.com/identity/complete\"\n}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.id_wallets.start_audkenni(\n    vendor_data=\"your-customer-reference\",\n    metadata={\"reference\": \"example\"},\n    country=\"ISL\",\n    return_url=\"https://app.example.com/identity/complete\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.idWallets.startAudkenni({\n  vendor_data: \"your-customer-reference\",\n  metadata: { reference: \"example\" },\n  country: \"ISL\",\n  return_url: \"https://app.example.com/identity/complete\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.IDWallets.StartAudkenni(ctx, didit.IDWalletsStartAudkenniParams{\n\tBody: didit.DigitalIDWalletAPIAudkenniWalletVerificationStartRequest{\n\t\tVendorData: didit.String(\"your-customer-reference\"),\n\t\tMetadata:   didit.Some(map[string]any{\"reference\": \"example\"}),\n\t\tCountry:    didit.Some(didit.DigitalIDWalletAPIAudkenniWalletVerificationStartCountryEnum(\"ISL\")),\n\t\tReturnURL:  \"https://app.example.com/identity/complete\",\n\t},\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.DigitalIdWalletApiAudkenniWalletVerificationStartCountryEnum;\nimport me.didit.types.DigitalIdWalletApiAudkenniWalletVerificationStartRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.idWallets().startAudkenni(DigitalIdWalletApiAudkenniWalletVerificationStartRequest.builder()\n        .vendorData(\"your-customer-reference\")\n        .metadata(Map.of(\"reference\", \"example\"))\n        .country(DigitalIdWalletApiAudkenniWalletVerificationStartCountryEnum.of(\"ISL\"))\n        .returnUrl(\"https://app.example.com/identity/complete\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->idWallets->startAudkenni([\n    'vendor_data' => 'your-customer-reference',\n    'metadata' => ['reference' => 'example'],\n    'country' => 'ISL',\n    'return_url' => 'https://app.example.com/identity/complete',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.id_wallets.start_audkenni(\n  vendor_data: \"your-customer-reference\",\n  metadata: { reference: \"example\" },\n  country: \"ISL\",\n  return_url: \"https://app.example.com/identity/complete\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.IdWallets.StartAudkenniAsync(new DigitalIdWalletApiAudkenniWalletVerificationStartRequest\n{\n    VendorData = \"your-customer-reference\",\n    Metadata = new Dictionary<string, object> { [\"reference\"] = \"example\" },\n    Country = new DigitalIdWalletApiAudkenniWalletVerificationStartCountryEnum(\"ISL\"),\n    ReturnUrl = \"https://app.example.com/identity/complete\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "x-didit-wallet-id": "audkenni"
      }
    },
    "/v3/id-verification/wallets/connectid/": {
      "post": {
        "operationId": "start_connectid_wallet_verification",
        "x-didit-sdk": {
          "resource": "id_wallets",
          "method": "start_connectid",
          "auth": "api_key",
          "server": true
        },
        "description": "Mulai proses masuk ConnectID (Australian Payments Plus; AUS) tanpa alur kerja apa pun. Ditagih sekali, hanya ketika identitas terverifikasi. Respons membawa next_action.type=redirect beserta URL untuk mengarahkan browser pengguna; pengguna kembali ke return_url dengan request_id dan result yang dilampirkan. Baca hasilnya dengan GET /v3/id-verification/wallets/verifications/{request_id}/ atau dari webhook, jangan pernah dari URL. Aplikasi sandbox mendapatkan simulasi deterministik (simulated: true) yang tidak pernah menghubungi penyedia.",
        "summary": "Mulai verifikasi ConnectID",
        "parameters": [
          {
            "in": "header",
            "name": "Idempotency-Key",
            "schema": {
              "type": "string"
            },
            "description": "Kunci keamanan coba lagi opsional (maks 255 karakter). Mencoba lagi dengan kunci, dompet, dan body yang sama akan mengembalikan verifikasi asli tanpa memulai proses masuk kedua; kunci yang sama dengan dompet atau body lain akan mengembalikan 409 idempotency_key_reused."
          }
        ],
        "tags": [
          "Digital ID wallets"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiConnectidWalletVerificationStartRequest"
              },
              "example": {
                "country": "AUS",
                "vendor_data": "your-customer-reference",
                "metadata": {
                  "reference": "example"
                },
                "return_url": "https://app.example.com/identity/complete"
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiConnectidWalletVerificationStartRequest"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiConnectidWalletVerificationStartRequest"
              }
            }
          },
          "required": true
        },
        "security": [
          {
            "ApiKeyAuth": []
          },
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationResponse"
                },
                "example": {
                  "request_id": "00000000-0000-4000-8000-000000000001",
                  "wallet_verification": {
                    "wallet": {
                      "id": "connectid",
                      "name": "ConnectID",
                      "issuing_authority": "Australian Payments Plus"
                    },
                    "country": "AUS",
                    "status": "Not Finished",
                    "outcome": "pending",
                    "error": null,
                    "interaction": "redirect",
                    "simulated": false,
                    "expires_at": "2026-01-01T10:10:00Z",
                    "next_action": {
                      "type": "redirect",
                      "url": "https://wallet.example.com/authorize"
                    },
                    "identity": null,
                    "attributes": null,
                    "level_of_assurance": null,
                    "verified_at": null,
                    "signature_valid": null,
                    "credential_type": "person_identification"
                  },
                  "vendor_data": "your-customer-reference",
                  "metadata": {
                    "reference": "example"
                  },
                  "created_at": "2026-01-01T10:00:00Z"
                }
              }
            },
            "description": ""
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationStartBadRequest"
                }
              }
            },
            "description": "Error validasi kolom ({field: [messages]}), atau error return_url_invalid, return_url_not_allowed, invalid_personal_code, invalid_phone_number, atau idempotency_key_invalid."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationStartForbidden"
                }
              }
            },
            "description": "Kredensial tidak ada ({detail}), atau kesalahan wallet_unavailable, insufficient_credits, atau contract_rate_missing."
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "kesalahan idempotency_key_reused atau idempotency_key_in_progress (dengan Retry-After)."
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "kesalahan wallet_provider_unavailable: penyedia tidak dapat memulai; tidak ada yang dibuat."
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "kesalahan wallet_not_configured: lingkungan ini tidak dapat menjangkau dompet."
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL",
            "source": "curl --request POST \\\n  --url https://verification.didit.me/v3/id-verification/wallets/connectid/ \\\n  --header 'x-api-key: YOUR_API_KEY' \\\n  --header 'Idempotency-Key: your-unique-attempt-key' \\\n  --header 'Content-Type: application/json' \\\n  --data '{\n  \"country\": \"AUS\",\n  \"vendor_data\": \"your-customer-reference\",\n  \"metadata\": {\n    \"reference\": \"example\"\n  },\n  \"return_url\": \"https://app.example.com/identity/complete\"\n}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.id_wallets.start_connectid(\n    vendor_data=\"your-customer-reference\",\n    metadata={\"reference\": \"example\"},\n    country=\"AUS\",\n    return_url=\"https://app.example.com/identity/complete\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.idWallets.startConnectid({\n  vendor_data: \"your-customer-reference\",\n  metadata: { reference: \"example\" },\n  country: \"AUS\",\n  return_url: \"https://app.example.com/identity/complete\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.IDWallets.StartConnectid(ctx, didit.IDWalletsStartConnectidParams{\n\tBody: didit.DigitalIDWalletAPIConnectidWalletVerificationStartRequest{\n\t\tVendorData: didit.String(\"your-customer-reference\"),\n\t\tMetadata:   didit.Some(map[string]any{\"reference\": \"example\"}),\n\t\tCountry:    didit.Some(didit.DigitalIDWalletAPIConnectidWalletVerificationStartCountryEnum(\"AUS\")),\n\t\tReturnURL:  \"https://app.example.com/identity/complete\",\n\t},\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.DigitalIdWalletApiConnectidWalletVerificationStartCountryEnum;\nimport me.didit.types.DigitalIdWalletApiConnectidWalletVerificationStartRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.idWallets().startConnectid(DigitalIdWalletApiConnectidWalletVerificationStartRequest.builder()\n        .vendorData(\"your-customer-reference\")\n        .metadata(Map.of(\"reference\", \"example\"))\n        .country(DigitalIdWalletApiConnectidWalletVerificationStartCountryEnum.of(\"AUS\"))\n        .returnUrl(\"https://app.example.com/identity/complete\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->idWallets->startConnectid([\n    'vendor_data' => 'your-customer-reference',\n    'metadata' => ['reference' => 'example'],\n    'country' => 'AUS',\n    'return_url' => 'https://app.example.com/identity/complete',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.id_wallets.start_connectid(\n  vendor_data: \"your-customer-reference\",\n  metadata: { reference: \"example\" },\n  country: \"AUS\",\n  return_url: \"https://app.example.com/identity/complete\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.IdWallets.StartConnectidAsync(new DigitalIdWalletApiConnectidWalletVerificationStartRequest\n{\n    VendorData = \"your-customer-reference\",\n    Metadata = new Dictionary<string, object> { [\"reference\"] = \"example\" },\n    Country = new DigitalIdWalletApiConnectidWalletVerificationStartCountryEnum(\"AUS\"),\n    ReturnUrl = \"https://app.example.com/identity/complete\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "x-didit-wallet-id": "connectid"
      }
    },
    "/v3/id-verification/wallets/eudi/": {
      "post": {
        "operationId": "start_eudi_wallet_verification",
        "x-didit-sdk": {
          "resource": "id_wallets",
          "method": "start_eudi",
          "auth": "api_key",
          "server": true
        },
        "description": "Mulai proses masuk EUDI Wallet (Negara anggota pengguna sendiri; penerbit berbeda per negara; AUT, BEL, BGR, HRV, CYP, CZE, DNK, EST, FIN, FRA, DEU, GRC, HUN, IRL, ITA, LVA, LTU, LUX, MLT, NLD, POL, PRT, ROU, SVK, SVN, ESP, SWE, ISL, LIE, NOR) tanpa alur kerja apa pun. Ditagih sekali, hanya ketika identitas terverifikasi. Respons membawa next_action.type=redirect beserta URL untuk mengarahkan browser pengguna; pengguna kembali ke return_url dengan request_id dan result yang dilampirkan. Baca hasilnya dengan GET /v3/id-verification/wallets/verifications/{request_id}/ atau dari webhook, jangan pernah dari URL. Aplikasi sandbox mendapatkan simulasi deterministik (simulated: true) yang tidak pernah menghubungi penyedia.",
        "summary": "Mulai verifikasi EUDI Wallet",
        "parameters": [
          {
            "in": "header",
            "name": "Idempotency-Key",
            "schema": {
              "type": "string"
            },
            "description": "Kunci keamanan coba lagi opsional (maks 255 karakter). Mencoba lagi dengan kunci, dompet, dan body yang sama akan mengembalikan verifikasi asli tanpa memulai proses masuk kedua; kunci yang sama dengan dompet atau body lain akan mengembalikan 409 idempotency_key_reused."
          }
        ],
        "tags": [
          "Digital ID wallets"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiEudiWalletVerificationStartRequest"
              },
              "example": {
                "country": "AUT",
                "vendor_data": "your-customer-reference",
                "metadata": {
                  "reference": "example"
                },
                "return_url": "https://app.example.com/identity/complete"
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiEudiWalletVerificationStartRequest"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiEudiWalletVerificationStartRequest"
              }
            }
          },
          "required": true
        },
        "security": [
          {
            "ApiKeyAuth": []
          },
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationResponse"
                },
                "example": {
                  "request_id": "00000000-0000-4000-8000-000000000001",
                  "wallet_verification": {
                    "wallet": {
                      "id": "eudi",
                      "name": "EUDI Wallet",
                      "issuing_authority": "The user's own member state; the issuer differs per country"
                    },
                    "country": "AUT",
                    "status": "Not Finished",
                    "outcome": "pending",
                    "error": null,
                    "interaction": "redirect",
                    "simulated": false,
                    "expires_at": "2026-01-01T10:10:00Z",
                    "next_action": {
                      "type": "redirect",
                      "url": "https://wallet.example.com/authorize"
                    },
                    "identity": null,
                    "attributes": null,
                    "level_of_assurance": null,
                    "verified_at": null,
                    "signature_valid": null,
                    "credential_type": "person_identification"
                  },
                  "vendor_data": "your-customer-reference",
                  "metadata": {
                    "reference": "example"
                  },
                  "created_at": "2026-01-01T10:00:00Z"
                }
              }
            },
            "description": ""
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationStartBadRequest"
                }
              }
            },
            "description": "Error validasi kolom ({field: [messages]}), atau error return_url_invalid, return_url_not_allowed, invalid_personal_code, invalid_phone_number, atau idempotency_key_invalid."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationStartForbidden"
                }
              }
            },
            "description": "Kredensial tidak ada ({detail}), atau kesalahan wallet_unavailable, insufficient_credits, atau contract_rate_missing."
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "kesalahan idempotency_key_reused atau idempotency_key_in_progress (dengan Retry-After)."
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "kesalahan wallet_provider_unavailable: penyedia tidak dapat memulai; tidak ada yang dibuat."
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "kesalahan wallet_not_configured: lingkungan ini tidak dapat menjangkau dompet."
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL",
            "source": "curl --request POST \\\n  --url https://verification.didit.me/v3/id-verification/wallets/eudi/ \\\n  --header 'x-api-key: YOUR_API_KEY' \\\n  --header 'Idempotency-Key: your-unique-attempt-key' \\\n  --header 'Content-Type: application/json' \\\n  --data '{\n  \"country\": \"AUT\",\n  \"vendor_data\": \"your-customer-reference\",\n  \"metadata\": {\n    \"reference\": \"example\"\n  },\n  \"return_url\": \"https://app.example.com/identity/complete\"\n}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.id_wallets.start_eudi(\n    vendor_data=\"your-customer-reference\",\n    metadata={\"reference\": \"example\"},\n    country=\"AUT\",\n    return_url=\"https://app.example.com/identity/complete\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.idWallets.startEudi({\n  vendor_data: \"your-customer-reference\",\n  metadata: { reference: \"example\" },\n  country: \"AUT\",\n  return_url: \"https://app.example.com/identity/complete\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.IDWallets.StartEudi(ctx, didit.IDWalletsStartEudiParams{\n\tBody: didit.DigitalIDWalletAPIEudiWalletVerificationStartRequest{\n\t\tVendorData: didit.String(\"your-customer-reference\"),\n\t\tMetadata:   didit.Some(map[string]any{\"reference\": \"example\"}),\n\t\tCountry:    didit.DigitalIDWalletAPIEudiWalletVerificationStartCountryEnum(\"AUT\"),\n\t\tReturnURL:  \"https://app.example.com/identity/complete\",\n\t},\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.DigitalIdWalletApiEudiWalletVerificationStartCountryEnum;\nimport me.didit.types.DigitalIdWalletApiEudiWalletVerificationStartRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.idWallets().startEudi(DigitalIdWalletApiEudiWalletVerificationStartRequest.builder()\n        .vendorData(\"your-customer-reference\")\n        .metadata(Map.of(\"reference\", \"example\"))\n        .country(DigitalIdWalletApiEudiWalletVerificationStartCountryEnum.of(\"AUT\"))\n        .returnUrl(\"https://app.example.com/identity/complete\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->idWallets->startEudi([\n    'vendor_data' => 'your-customer-reference',\n    'metadata' => ['reference' => 'example'],\n    'country' => 'AUT',\n    'return_url' => 'https://app.example.com/identity/complete',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.id_wallets.start_eudi(\n  vendor_data: \"your-customer-reference\",\n  metadata: { reference: \"example\" },\n  country: \"AUT\",\n  return_url: \"https://app.example.com/identity/complete\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.IdWallets.StartEudiAsync(new DigitalIdWalletApiEudiWalletVerificationStartRequest\n{\n    VendorData = \"your-customer-reference\",\n    Metadata = new Dictionary<string, object> { [\"reference\"] = \"example\" },\n    Country = \"AUT\",\n    ReturnUrl = \"https://app.example.com/identity/complete\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "x-didit-wallet-id": "eudi"
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/cases/teams/": {
      "get": {
        "summary": "Mencantumkan tim peninjau",
        "description": "Memerlukan `list:cases` untuk aplikasi yang diminta.",
        "operationId": "list_case_teams",
        "x-didit-sdk": {
          "resource": "cases.teams",
          "method": "list",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Case Assignment"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID organisasi."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID aplikasi."
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 50
            }
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "maximum": 1000000,
              "default": 0
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Berhasil",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "results": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/CaseReviewTeam"
                      }
                    },
                    "count": {
                      "type": "integer",
                      "description": "Jumlah yang cocok, dibatasi maksimal 100. Gunakan next untuk melanjutkan setelah batas tersebut."
                    },
                    "next": {
                      "type": "string",
                      "nullable": true
                    },
                    "previous": {
                      "type": "string",
                      "nullable": true
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Input tidak valid."
          },
          "403": {
            "description": "Izin tidak memadai."
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nfor item in client.cases.teams.list():\n    print(item)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nfor await (const item of didit.cases.teams.list()) {\n  console.log(item);\n}"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\niter := client.Cases.Teams.ListAutoPaging(ctx, didit.CasesTeamsListParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nfor (var item : client.cases().teams().list()) {\n    System.out.println(item);\n}"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\nforeach ($didit->cases->teams->list() as $item) {\n    print_r($item->toArray());\n}"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\ndidit.cases.teams.list.auto_paging_each do |item|\n  puts item.to_h\nend"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.Cases.Teams.ListAsync())\n{\n    Console.WriteLine(JsonSerializer.Serialize(item));\n}"
          }
        ]
      },
      "post": {
        "summary": "Buat tim peninjau",
        "description": "Memerlukan `write:cases` untuk aplikasi yang diminta.",
        "operationId": "create_case_teams",
        "x-didit-sdk": {
          "resource": "cases.teams",
          "method": "create",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Case Assignment"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID organisasi."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID aplikasi."
          }
        ],
        "responses": {
          "201": {
            "description": "Berhasil",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CaseReviewTeam"
                }
              }
            }
          },
          "400": {
            "description": "Input tidak valid."
          },
          "403": {
            "description": "Izin tidak memadai."
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CaseReviewTeamCreate"
              },
              "example": {
                "name": "AML analysts",
                "members": [
                  {
                    "user_id": "9a000000-0000-4000-8000-0000000000aa",
                    "capacity": 10
                  }
                ]
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.teams.create(\n    name=\"AML analysts\",\n    members=[{\n        \"user_id\": \"9a000000-0000-4000-8000-0000000000aa\",\n        \"capacity\": 10,\n    }],\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.teams.create({\n  name: \"AML analysts\",\n  members: [{\n    user_id: \"9a000000-0000-4000-8000-0000000000aa\",\n    capacity: 10,\n  }],\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.Teams.Create(ctx, didit.CaseReviewTeamCreate{\n\tName: \"AML analysts\",\n\tMembers: []didit.CaseReviewTeamMemberParam{{\n\t\tUserID:   \"9a000000-0000-4000-8000-0000000000aa\",\n\t\tCapacity: didit.Int(10),\n\t}},\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.List;\nimport me.didit.Didit;\nimport me.didit.types.CaseReviewTeamCreate;\nimport me.didit.types.CaseReviewTeamMember;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().teams().create(CaseReviewTeamCreate.builder()\n        .name(\"AML analysts\")\n        .members(List.of(CaseReviewTeamMember.builder()\n                .userId(\"9a000000-0000-4000-8000-0000000000aa\")\n                .capacity(10L)\n                .build()))\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->cases->teams->create([\n    'name' => 'AML analysts',\n    'members' => [[\n        'user_id' => '9a000000-0000-4000-8000-0000000000aa',\n        'capacity' => 10,\n    ]],\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.teams.create(\n  name: \"AML analysts\",\n  members: [{\n    user_id: \"9a000000-0000-4000-8000-0000000000aa\",\n    capacity: 10,\n  }]\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.Teams.CreateAsync(new CaseReviewTeamCreate\n{\n    Name = \"AML analysts\",\n    Members = new CaseReviewTeamMember[]\n    {\n        new()\n        {\n            UserId = \"9a000000-0000-4000-8000-0000000000aa\",\n            Capacity = 10,\n        },\n    },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/fraud/checks/{check_id}/": {
      "get": {
        "operationId": "root_retrieve",
        "x-didit-sdk": {
          "resource": "fraud_checks",
          "method": "retrieve",
          "auth": "api_key",
          "server": true
        },
        "description": "Ambil pemeriksaan yang dibuat sebelumnya berdasarkan `check_id`-nya.",
        "summary": "Ambil Pemeriksaan Penipuan",
        "parameters": [
          {
            "in": "path",
            "name": "check_id",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FraudCheckResponse"
                }
              }
            },
            "description": ""
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FraudClientCredentialsErrorMessage"
                }
              }
            },
            "description": ""
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FraudClientCredentialsForbiddenErrorMessage"
                }
              }
            },
            "description": ""
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          },
          {
            "BearerAuth": []
          }
        ],
        "tags": [
          "Fraud Check"
        ],
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.fraud_checks.retrieve(\n    \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.fraudChecks.retrieve(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.FraudChecks.Retrieve(ctx, \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.fraudChecks().retrieve(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->fraudChecks->retrieve('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.fraud_checks.retrieve(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.FraudChecks.RetrieveAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/cases/{case_uuid}/requests/": {
      "get": {
        "operationId": "organization_application_cases_requests_list",
        "x-didit-sdk": {
          "resource": "cases.requests",
          "method": "list",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "parameters": [
          {
            "in": "path",
            "name": "organization_id",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          },
          {
            "in": "path",
            "name": "application_id",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          },
          {
            "in": "path",
            "name": "case_uuid",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          },
          {
            "name": "ordering",
            "required": false,
            "in": "query",
            "description": "Kolom mana yang digunakan saat mengurutkan hasil.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "description": "Jumlah hasil yang dikembalikan per halaman.",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "offset",
            "required": false,
            "in": "query",
            "description": "Indeks awal yang digunakan untuk mengembalikan hasil.",
            "schema": {
              "type": "integer"
            }
          }
        ],
        "tags": [
          "Case Management"
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CustomerMessagingPaginatedCaseRequestList"
                }
              }
            },
            "description": ""
          },
          "404": {
            "description": "Permintaan atau kasus tidak tersedia untuk pemanggil ini."
          },
          "403": {
            "description": "Pemanggil tidak memiliki izin kasus yang diperlukan."
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nfor item in client.cases.requests.list(\n    \"11111111-2222-3333-4444-555555555555\",\n):\n    print(item)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nfor await (const item of didit.cases.requests.list(\"11111111-2222-3333-4444-555555555555\")) {\n  console.log(item);\n}"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\niter := client.Cases.Requests.ListAutoPaging(ctx, \"11111111-2222-3333-4444-555555555555\", didit.CasesRequestsListParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nfor (var item : client.cases().requests().list(\"11111111-2222-3333-4444-555555555555\")) {\n    System.out.println(item);\n}"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\nforeach ($didit->cases->requests->list('11111111-2222-3333-4444-555555555555') as $item) {\n    print_r($item->toArray());\n}"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\ndidit.cases.requests.list(\"11111111-2222-3333-4444-555555555555\").auto_paging_each do |item|\n  puts item.to_h\nend"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.Cases.Requests.ListAsync(\"11111111-2222-3333-4444-555555555555\"))\n{\n    Console.WriteLine(JsonSerializer.Serialize(item));\n}"
          }
        ]
      },
      "post": {
        "operationId": "organization_application_cases_requests_create",
        "x-didit-sdk": {
          "resource": "cases.requests",
          "method": "create",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "parameters": [
          {
            "in": "path",
            "name": "organization_id",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          },
          {
            "in": "path",
            "name": "application_id",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          },
          {
            "in": "path",
            "name": "case_uuid",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          }
        ],
        "tags": [
          "Case Management"
        ],
        "requestBody": {
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/CustomerMessagingCaseRequestConfirmRequest"
              }
            },
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CustomerMessagingCaseRequestConfirmRequest"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/CustomerMessagingCaseRequestConfirmRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "404": {
            "description": "Permintaan atau kasus tidak tersedia untuk pemanggil ini."
          },
          "403": {
            "description": "Pemanggil tidak memiliki izin kasus yang diperlukan."
          },
          "400": {
            "description": "Input tidak valid, tujuan tidak didukung, kontak terverifikasi tidak tersedia, atau respons yang sudah ada tidak dapat diubah."
          },
          "409": {
            "description": "Pratinjau telah berubah atau kedaluwarsa. Tampilkan pratinjau lagi sebelum mengonfirmasi."
          },
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CustomerMessagingCaseRequest"
                }
              }
            },
            "description": ""
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "description": "Konfirmasikan pratinjau tertandatangani yang tepat dalam waktu 15 menit. Hanya templat tetap dan kontak terverifikasi OTP milik subjek kasus yang diterima. ID permintaan membuat percobaan ulang bersifat idempoten. Pengiriman dimasukkan ke antrean; SENT, SIMULATED, dan UNKNOWN adalah hasil yang berbeda. Permintaan yang dapat ditindaklanjuti mengatur kasus ke Menunggu pengguna. Pembaruan tinjauan membiarkan statusnya tidak berubah.",
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.requests.create(\n    \"11111111-2222-3333-4444-555555555555\",\n    contact_id=\"11111111-2222-3333-4444-555555555555\",\n    purpose=\"identity_document\",\n    request_id=\"11111111-2222-3333-4444-555555555555\",\n    expires_at=\"2026-01-15T10:00:00Z\",\n    preview_token=\"your-preview-token\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.requests.create(\"11111111-2222-3333-4444-555555555555\", {\n  contact_id: \"11111111-2222-3333-4444-555555555555\",\n  purpose: \"identity_document\",\n  request_id: \"11111111-2222-3333-4444-555555555555\",\n  expires_at: \"2026-01-15T10:00:00Z\",\n  preview_token: \"your-preview-token\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.Requests.Create(ctx, \"11111111-2222-3333-4444-555555555555\", didit.CustomerMessagingCaseRequestConfirmRequest{\n\tContactID:    \"11111111-2222-3333-4444-555555555555\",\n\tPurpose:      didit.CustomerMessagingPurposeEnum(\"identity_document\"),\n\tRequestID:    \"11111111-2222-3333-4444-555555555555\",\n\tExpiresAt:    time.Date(2026, 1, 15, 10, 0, 0, 0, time.UTC),\n\tPreviewToken: \"your-preview-token\",\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.time.OffsetDateTime;\nimport me.didit.Didit;\nimport me.didit.types.CustomerMessagingCaseRequestConfirmRequest;\nimport me.didit.types.CustomerMessagingPurposeEnum;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().requests().create(\"11111111-2222-3333-4444-555555555555\", CustomerMessagingCaseRequestConfirmRequest.builder()\n        .contactId(\"11111111-2222-3333-4444-555555555555\")\n        .purpose(CustomerMessagingPurposeEnum.of(\"identity_document\"))\n        .requestId(\"11111111-2222-3333-4444-555555555555\")\n        .expiresAt(OffsetDateTime.parse(\"2026-01-15T10:00:00Z\"))\n        .previewToken(\"your-preview-token\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->cases->requests->create('11111111-2222-3333-4444-555555555555', [\n    'contact_id' => '11111111-2222-3333-4444-555555555555',\n    'purpose' => 'identity_document',\n    'request_id' => '11111111-2222-3333-4444-555555555555',\n    'expires_at' => '2026-01-15T10:00:00Z',\n    'preview_token' => 'your-preview-token',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.requests.create(\n  \"11111111-2222-3333-4444-555555555555\",\n  contact_id: \"11111111-2222-3333-4444-555555555555\",\n  purpose: \"identity_document\",\n  request_id: \"11111111-2222-3333-4444-555555555555\",\n  expires_at: \"2026-01-15T10:00:00Z\",\n  preview_token: \"your-preview-token\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.Requests.CreateAsync(\"11111111-2222-3333-4444-555555555555\", new CustomerMessagingCaseRequestConfirmRequest\n{\n    ContactId = \"11111111-2222-3333-4444-555555555555\",\n    Purpose = \"identity_document\",\n    RequestId = \"11111111-2222-3333-4444-555555555555\",\n    ExpiresAt = DateTimeOffset.Parse(\"2026-01-15T10:00:00Z\"),\n    PreviewToken = \"your-preview-token\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/fraud/checks/": {
      "post": {
        "operationId": "create_fraud_check",
        "x-didit-sdk": {
          "resource": "fraud_checks",
          "method": "create",
          "auth": "api_key",
          "server": true
        },
        "description": "Kirim satu atau beberapa pengenal bertipe dan terima normalisasi, pengayaan terbaru, validasi otoritatif jika negara dan jenis pengenal didukung, dimensi risiko independen, serta rekomendasi dalam satu respons.\n\nProfil ini mendukung pemeriksaan pengenal. Pengikatan identitas berbasis swafoto (`biometric_identity`) memerlukan profil versi `2026-09-14.2` dan CPF Brasil; modul ini hanya berjalan dengan persetujuan pengguna dan jika organisasi Anda berhak atas fitur tersebut. Versi sebelumnya melaporkannya sebagai `not_available_in_profile_version`. Modul yang tidak dapat berjalan dilaporkan dilewati dengan alasan deterministik; sumber yang tidak dapat memberikan jawaban tidak pernah dilaporkan sebagai ketidakcocokan identitas.",
        "summary": "Jalankan Pemeriksaan Penipuan",
        "requestBody": {
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/FraudCheckRequestRequest"
              }
            },
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/FraudCheckRequestRequest"
              },
              "example": {
                "client_reference": "review-attempt-001",
                "subject": {
                  "identifiers": [
                    {
                      "type": "email",
                      "value": "applicant@example.com"
                    }
                  ],
                  "attributes": {
                    "first_name": "Alex",
                    "last_name": "Example"
                  }
                },
                "checks": {
                  "include": [
                    "networks_same_org",
                    "networks_cross_org",
                    "email_risk"
                  ]
                }
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/FraudCheckRequestRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FraudCheckResponse"
                }
              }
            },
            "description": ""
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FraudClientCredentialsErrorMessage"
                }
              }
            },
            "description": ""
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FraudClientCredentialsForbiddenErrorMessage"
                }
              }
            },
            "description": ""
          },
          "409": {
            "description": "Konflik, dikembalikan tanpa biaya: `client_reference` telah digunakan dengan isi permintaan yang berbeda; pemeriksaan dengan `client_reference` yang sama masih berjalan (coba lagi setelah `Retry-After` detik dengan referensi yang sama); atau verifikasi yang menjadi tempat pencatatan pemeriksaan ini telah dihapus sebelum pemeriksaan selesai.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "error"
                  ]
                },
                "examples": {
                  "different_body": {
                    "summary": "Referensi digunakan kembali dengan body yang berbeda",
                    "value": {
                      "error": "client_reference has already been used with a different request body."
                    }
                  },
                  "still_running": {
                    "summary": "Pemeriksaan dengan referensi ini masih berjalan",
                    "value": {
                      "error": "A check with this client_reference is already running. Retry with the same reference later."
                    }
                  },
                  "verification_deleted": {
                    "summary": "Verifikasi dihapus sebelum pemeriksaan selesai",
                    "value": {
                      "error": "This verification was deleted before the check completed."
                    }
                  }
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Detik yang harus ditunggu sebelum mencoba lagi, dikirim saat pemeriksaan dengan `client_reference` yang sama masih berjalan.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          },
          {
            "BearerAuth": []
          }
        ],
        "tags": [
          "Fraud Check"
        ],
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.fraud_checks.create(\n    client_reference=\"review-attempt-001\",\n    subject={\n        \"identifiers\": [{\n            \"type\": \"email\",\n            \"value\": \"applicant@example.com\",\n        }],\n        \"attributes\": {\n            \"first_name\": \"Alex\",\n            \"last_name\": \"Example\",\n        },\n    },\n    checks={\n        \"include\": [\"networks_same_org\", \"networks_cross_org\", \"email_risk\"],\n    },\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.fraudChecks.create({\n  client_reference: \"review-attempt-001\",\n  subject: {\n    identifiers: [{\n      type: \"email\",\n      value: \"applicant@example.com\",\n    }],\n    attributes: {\n      first_name: \"Alex\",\n      last_name: \"Example\",\n    },\n  },\n  checks: {\n    include: [\"networks_same_org\", \"networks_cross_org\", \"email_risk\"],\n  },\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.FraudChecks.Create(ctx, didit.FraudCheckRequestRequest{\n\tClientReference: didit.String(\"review-attempt-001\"),\n\tSubject: didit.FraudCheckSubjectRequest{\n\t\tIdentifiers: []didit.FraudCheckIdentifierRequest{{\n\t\t\tType:  didit.FraudTypeEnum(\"email\"),\n\t\t\tValue: \"applicant@example.com\",\n\t\t}},\n\t\tAttributes: didit.Some(didit.FraudCheckAttributesRequest{\n\t\t\tFirstName: didit.String(\"Alex\"),\n\t\t\tLastName:  didit.String(\"Example\"),\n\t\t}),\n\t},\n\tChecks: didit.Some(didit.FraudCheckModuleSelectionRequest{\n\t\tInclude: didit.Some([]didit.FraudExcludeEnum{didit.FraudExcludeEnum(\"networks_same_org\"), didit.FraudExcludeEnum(\"networks_cross_org\"), didit.FraudExcludeEnum(\"email_risk\")}),\n\t}),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.List;\nimport me.didit.Didit;\nimport me.didit.types.FraudCheckAttributesRequest;\nimport me.didit.types.FraudCheckIdentifierRequest;\nimport me.didit.types.FraudCheckModuleSelectionRequest;\nimport me.didit.types.FraudCheckRequestRequest;\nimport me.didit.types.FraudCheckSubjectRequest;\nimport me.didit.types.FraudExcludeEnum;\nimport me.didit.types.FraudTypeEnum;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.fraudChecks().create(FraudCheckRequestRequest.builder()\n        .clientReference(\"review-attempt-001\")\n        .subject(FraudCheckSubjectRequest.builder()\n                .identifiers(List.of(FraudCheckIdentifierRequest.builder()\n                        .type(FraudTypeEnum.of(\"email\"))\n                        .value(\"applicant@example.com\")\n                        .build()))\n                .attributes(FraudCheckAttributesRequest.builder()\n                        .firstName(\"Alex\")\n                        .lastName(\"Example\")\n                        .build())\n                .build())\n        .checks(FraudCheckModuleSelectionRequest.builder()\n                .include(List.of(FraudExcludeEnum.of(\"networks_same_org\"), FraudExcludeEnum.of(\"networks_cross_org\"), FraudExcludeEnum.of(\"email_risk\")))\n                .build())\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->fraudChecks->create([\n    'client_reference' => 'review-attempt-001',\n    'subject' => [\n        'identifiers' => [[\n            'type' => 'email',\n            'value' => 'applicant@example.com',\n        ]],\n        'attributes' => [\n            'first_name' => 'Alex',\n            'last_name' => 'Example',\n        ],\n    ],\n    'checks' => [\n        'include' => ['networks_same_org', 'networks_cross_org', 'email_risk'],\n    ],\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.fraud_checks.create(\n  client_reference: \"review-attempt-001\",\n  subject: {\n    identifiers: [{\n      type: \"email\",\n      value: \"applicant@example.com\",\n    }],\n    attributes: {\n      first_name: \"Alex\",\n      last_name: \"Example\",\n    },\n  },\n  checks: {\n    include: [\"networks_same_org\", \"networks_cross_org\", \"email_risk\"],\n  }\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.FraudChecks.CreateAsync(new FraudCheckRequestRequest\n{\n    ClientReference = \"review-attempt-001\",\n    Subject = new()\n    {\n        Identifiers = new FraudCheckIdentifierRequest[]\n        {\n            new()\n            {\n                Type = \"email\",\n                Value = \"applicant@example.com\",\n            },\n        },\n        Attributes = new FraudCheckAttributesRequest\n        {\n            FirstName = \"Alex\",\n            LastName = \"Example\",\n        },\n    },\n    Checks = new FraudCheckModuleSelectionRequest\n    {\n        Include = new FraudExcludeEnum[] { \"networks_same_org\", \"networks_cross_org\", \"email_risk\" },\n    },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/cases/{case_uuid}/requests/{request_uuid}/cancel/": {
      "post": {
        "operationId": "organization_application_cases_requests_cancel_create",
        "x-didit-sdk": {
          "resource": "cases.requests",
          "method": "cancel",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "parameters": [
          {
            "in": "path",
            "name": "organization_id",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          },
          {
            "in": "path",
            "name": "application_id",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          },
          {
            "in": "path",
            "name": "case_uuid",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          },
          {
            "in": "path",
            "name": "request_uuid",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          }
        ],
        "tags": [
          "Case Management"
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CustomerMessagingCaseRequest"
                }
              }
            },
            "description": ""
          },
          "404": {
            "description": "Permintaan atau kasus tidak tersedia untuk pemanggil ini."
          },
          "403": {
            "description": "Pemanggil tidak memiliki izin kasus yang diperlukan."
          },
          "400": {
            "description": "Input tidak valid, tujuan tidak didukung, kontak terverifikasi tidak tersedia, atau respons yang sudah ada tidak dapat diubah."
          },
          "409": {
            "description": "Pratinjau telah berubah atau kedaluwarsa. Tampilkan pratinjau lagi sebelum mengonfirmasi."
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.requests.cancel(\n    \"11111111-2222-3333-4444-555555555555\",\n    \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.requests.cancel(\n  \"11111111-2222-3333-4444-555555555555\",\n  \"11111111-2222-3333-4444-555555555555\",\n);\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.Requests.Cancel(ctx, \"11111111-2222-3333-4444-555555555555\", \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().requests().cancel(\"11111111-2222-3333-4444-555555555555\", \"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->cases->requests->cancel('11111111-2222-3333-4444-555555555555', '11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.requests.cancel(\n  \"11111111-2222-3333-4444-555555555555\",\n  \"11111111-2222-3333-4444-555555555555\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.Requests.CancelAsync(\"11111111-2222-3333-4444-555555555555\", \"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/cases/{case_uuid}/requests/options/": {
      "get": {
        "operationId": "organization_application_cases_requests_options_retrieve",
        "x-didit-sdk": {
          "resource": "cases.requests",
          "method": "retrieve_options",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "parameters": [
          {
            "in": "path",
            "name": "organization_id",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          },
          {
            "in": "path",
            "name": "application_id",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          },
          {
            "in": "path",
            "name": "case_uuid",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          }
        ],
        "tags": [
          "Case Management"
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CustomerMessagingCaseRequestOptions"
                }
              }
            },
            "description": ""
          },
          "404": {
            "description": "Permintaan atau kasus tidak tersedia untuk pemanggil ini."
          },
          "403": {
            "description": "Pemanggil tidak memiliki izin kasus yang diperlukan."
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.requests.retrieve_options(\n    \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.requests.retrieveOptions(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.Requests.RetrieveOptions(ctx, \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().requests().retrieveOptions(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->cases->requests->retrieveOptions('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.requests.retrieve_options(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.Requests.RetrieveOptionsAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/cases/{case_uuid}/requests/{request_uuid}/attachment/": {
      "get": {
        "operationId": "organization_application_cases_requests_attachment_retrieve",
        "x-didit-sdk": {
          "resource": "cases.requests",
          "method": "retrieve_attachment",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "parameters": [
          {
            "in": "path",
            "name": "organization_id",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          },
          {
            "in": "path",
            "name": "application_id",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          },
          {
            "in": "path",
            "name": "case_uuid",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          },
          {
            "in": "path",
            "name": "request_uuid",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          }
        ],
        "tags": [
          "Case Management"
        ],
        "responses": {
          "200": {
            "content": {
              "image/jpeg": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            },
            "description": ""
          },
          "404": {
            "description": "Permintaan atau kasus tidak tersedia untuk pemanggil ini."
          },
          "403": {
            "description": "Pemanggil tidak memiliki izin kasus yang diperlukan."
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\ncontent = client.cases.requests.retrieve_attachment(\n    \"11111111-2222-3333-4444-555555555555\",\n    \"11111111-2222-3333-4444-555555555555\",\n)\nwith open(\"download.png\", \"wb\") as file:\n    file.write(content)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import { writeFile } from \"node:fs/promises\";\nimport Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst content = await didit.cases.requests.retrieveAttachment(\n  \"11111111-2222-3333-4444-555555555555\",\n  \"11111111-2222-3333-4444-555555555555\",\n);\nawait writeFile(\"download.png\", Buffer.from(await content.arrayBuffer()));"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresp, err := client.Cases.Requests.RetrieveAttachment(ctx, \"11111111-2222-3333-4444-555555555555\", \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\ndefer resp.Body.Close()\nfile, err := os.Create(\"download.png\")\nif err != nil {\n\tlog.Fatal(err)\n}\ndefer file.Close()\nif _, err := io.Copy(file, resp.Body); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.nio.file.Path;\nimport me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nclient.cases().requests().retrieveAttachment(\"11111111-2222-3333-4444-555555555555\", \"11111111-2222-3333-4444-555555555555\")\n        .writeTo(Path.of(\"download.png\"));"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$content = $didit->cases->requests->retrieveAttachment('11111111-2222-3333-4444-555555555555', '11111111-2222-3333-4444-555555555555');\n$content->saveTo('download.png');"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\ncontent = didit.cases.requests.retrieve_attachment(\n  \"11111111-2222-3333-4444-555555555555\",\n  \"11111111-2222-3333-4444-555555555555\"\n)\nFile.binwrite(\"download.png\", content)"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar content = await client.Cases.Requests.RetrieveAttachmentAsync(\"11111111-2222-3333-4444-555555555555\", \"11111111-2222-3333-4444-555555555555\");\nawait content.SaveToAsync(\"download.png\");"
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/cases/routing-rules/{record_uuid}/history/": {
      "get": {
        "operationId": "list_case_routing_rule_history",
        "x-didit-sdk": {
          "resource": "cases.routing_rules",
          "method": "list_history",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "parameters": [
          {
            "in": "path",
            "name": "organization_id",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          },
          {
            "in": "path",
            "name": "application_id",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          },
          {
            "in": "path",
            "name": "record_uuid",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          },
          {
            "name": "ordering",
            "required": false,
            "in": "query",
            "description": "Kolom mana yang digunakan saat mengurutkan hasil.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "description": "Jumlah hasil yang dikembalikan per halaman.",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "offset",
            "required": false,
            "in": "query",
            "description": "Indeks awal yang digunakan untuk mengembalikan hasil.",
            "schema": {
              "type": "integer"
            }
          }
        ],
        "tags": [
          "Case Assignment"
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RoutingPublicationPaginatedPolicyRevisionList"
                }
              }
            },
            "description": ""
          },
          "403": {
            "description": "Akses kasus diperlukan."
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nfor item in client.cases.routing_rules.list_history(\n    \"11111111-2222-3333-4444-555555555555\",\n):\n    print(item)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nfor await (const item of didit.cases.routingRules.listHistory(\"11111111-2222-3333-4444-555555555555\")) {\n  console.log(item);\n}"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\niter := client.Cases.RoutingRules.ListHistoryAutoPaging(ctx, \"11111111-2222-3333-4444-555555555555\", didit.CasesRoutingRulesListHistoryParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nfor (var item : client.cases().routingRules().listHistory(\"11111111-2222-3333-4444-555555555555\")) {\n    System.out.println(item);\n}"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\nforeach ($didit->cases->routingRules->listHistory('11111111-2222-3333-4444-555555555555') as $item) {\n    print_r($item->toArray());\n}"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\ndidit.cases.routing_rules.list_history(\"11111111-2222-3333-4444-555555555555\").auto_paging_each do |item|\n  puts item.to_h\nend"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.Cases.RoutingRules.ListHistoryAsync(\"11111111-2222-3333-4444-555555555555\"))\n{\n    Console.WriteLine(JsonSerializer.Serialize(item));\n}"
          }
        ]
      }
    },
    "/v3/session/{sessionId}/resubmission-preview/": {
      "post": {
        "summary": "Pratinjau email pengiriman ulang",
        "description": "Me-render email yang akan menyertai pengiriman ulang KYC atau KYB tanpa mengubah sesi, mengatur ulang pemeriksaan, memperpanjang masa kedaluwarsanya, menjalankan pemeriksaan, atau mengirim email. Memerlukan hak istimewa `write:sessions` (kunci API ber-scope memerlukan akses tulis ke keputusan) dan sesi dalam status `Approved`, `Declined`, `In Review`, `Kyc Expired`, atau `Abandoned`. Server memvalidasi langkah alur kerja yang dipilih dan me-render templat terjemahan tetapnya dengan pengirim White Label terverifikasi dan branding yang berlaku. Permintaan tidak dapat menetapkan subjek, isi pesan, atau URL tindakan.\n\n`email_address` bersifat opsional. Tanpa parameter ini, email akan dikirim ke alamat pengguna itu sendiri: alamat yang mereka verifikasi dalam langkah verifikasi email pada alur, atau alamat yang diberikan di `contact_details` saat sesi dibuat. Alamat yang Anda teruskan akan diutamakan (`recipient_source: request`). Jika tidak ada alamat yang diketahui dan Anda tidak meneruskannya, `recipient` dan `preview_token` berupa string kosong dan email tidak dapat dikirim.\n\nRespons mencakup penerima dan asal alamatnya, pengirim, subjek, HTML, bahasa, langkah yang telah ditentukan, apakah konfirmasi akan mengirim email (`will_be_sent`, `not_sent_reason`), serta `preview_token` yang ditandatangani. `requires_user_action` bernilai `false` jika setiap langkah yang dipilih berjalan tanpa pengguna: pengiriman ulang kemudian selesai dengan sendirinya dan tidak ada email yang dikirim (`not_sent_reason: no_user_action`).\n\nPratinjau ini tidak mencadangkan status sesi atau mengotorisasi pengiriman. Setelah meninjaunya, panggil [Update Session Status](/id/sessions-api/update-status) dengan `new_status: Resubmitted`, `nodes_to_resubmit` dan `email_language` yang sama seperti yang Anda pratinjau, `send_email: true`, `email_address` disetel ke `recipient`, dan `email_preview_token` disetel ke `preview_token`. Tanda terima kedaluwarsa setelah 15 menit. Saat tanda terima disertakan, perubahan input, konten pesan, pengirim, atau status sesi akan mengembalikan `409` sebelum mutasi atau pengiriman apa pun dilakukan. Integrasi yang sudah ada dapat mengabaikan tanda terima. Buat ulang pratinjau setelah terjadi konflik. Perlakukan respons sebagai konten verifikasi sensitif; respons menggunakan `Cache-Control: no-store`. Render HTML dalam frame sandbox, jangan pernah langsung di dalam DOM aplikasi Anda.",
        "operationId": "post_v3_session_resubmission_preview",
        "x-didit-sdk": {
          "resource": "sessions",
          "method": "preview_resubmission",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Sessions"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "in": "path",
            "name": "sessionId",
            "required": true,
            "description": "UUID sesi verifikasi yang akan diperbarui. Menerima ID sesi pengguna (KYC) dan bisnis (KYB) — layanan mencari ID tersebut di kedua jenis sesi.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "11111111-2222-3333-4444-555555555555"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "nodes_to_resubmit": {
                    "type": "array",
                    "description": "Langkah-langkah yang akan dipratinjau, menggunakan validasi, pemilihan, dan urutan alur kerja yang sama seperti pengiriman ulang. Jangan sertakan untuk memilih otomatis percobaan tercatat yang memerlukan pengiriman ulang.",
                    "items": {
                      "type": "object",
                      "required": [
                        "node_id",
                        "feature"
                      ],
                      "properties": {
                        "node_id": {
                          "type": "string",
                          "description": "Pengenal node seperti yang muncul dalam definisi alur kerja sesi (misalnya `feature_ocr`, `feature_liveness`).",
                          "example": "feature_ocr"
                        },
                        "feature": {
                          "type": "string",
                          "description": "Tipe fitur dari node. Alias `ID_VERIFICATION`, `POA`, `PHONE`, dan `EMAIL` dinormalisasi di sisi server menjadi `OCR`, `PROOF_OF_ADDRESS`, `PHONE_VERIFICATION`, dan `EMAIL_VERIFICATION`. `KYB_REGISTRY`, `KYB_KEY_PEOPLE`, dan `KYB` lolos validasi skema tetapi selalu ditolak dengan aturan bisnis `400` yang ditunjukkan pada contoh.",
                          "enum": [
                            "OCR",
                            "OCR_BACK",
                            "NFC",
                            "AML",
                            "FACE",
                            "LIVENESS",
                            "FACE_MATCH",
                            "IP_ANALYSIS",
                            "AGE_ESTIMATION",
                            "PROOF_OF_ADDRESS",
                            "PHONE_VERIFICATION",
                            "EMAIL_VERIFICATION",
                            "FACE_SEARCH",
                            "DATABASE_VALIDATION",
                            "QUESTIONNAIRE",
                            "DOCUMENT_AI",
                            "KYB_DOCUMENTS",
                            "ID_VERIFICATION",
                            "POA",
                            "PHONE",
                            "EMAIL",
                            "KYB_REGISTRY",
                            "KYB_KEY_PEOPLE",
                            "KYB",
                            "GEOLOCATION"
                          ],
                          "example": "OCR"
                        }
                      }
                    }
                  },
                  "email_address": {
                    "type": "string",
                    "format": "email",
                    "description": "Opsional. Kirim email ke alamat ini alih-alih alamat orang itu sendiri. Tanpa parameter ini, penerima adalah alamat yang diverifikasi orang tersebut dalam alur, atau yang diberikan di `contact_details`. Tidak ada email yang dikirim oleh panggilan ini.",
                    "example": "user@example.com"
                  },
                  "email_language": {
                    "type": "string",
                    "description": "Bahasa untuk email notifikasi. Menerima string apa pun pada tingkat skema; kode yang tidak didukung akan beralih ke bahasa Inggris (`en`) secara senyap.",
                    "default": "en",
                    "example": "en"
                  }
                }
              },
              "examples": {
                "Person's Own Address": {
                  "summary": "Pratinjau pengiriman ulang bukti alamat untuk alamat orang tersebut sendiri",
                  "value": {
                    "nodes_to_resubmit": [
                      {
                        "node_id": "feature_poa_1",
                        "feature": "POA"
                      }
                    ],
                    "email_language": "en"
                  }
                },
                "Named Recipient": {
                  "summary": "Pratinjau email untuk alamat yang Anda tentukan",
                  "value": {
                    "nodes_to_resubmit": [
                      {
                        "node_id": "feature_ocr",
                        "feature": "OCR"
                      }
                    ],
                    "email_address": "person@example.com",
                    "email_language": "en"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Hanya pratinjau. Sesi tidak berubah dan tidak ada email yang dikirim.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "recipient",
                    "recipient_source",
                    "sender",
                    "sender_name",
                    "sender_email",
                    "sender_kind",
                    "subject",
                    "html",
                    "text",
                    "language",
                    "will_be_sent",
                    "not_sent_reason",
                    "preview_token",
                    "nodes_to_resubmit",
                    "requires_user_action"
                  ],
                  "properties": {
                    "recipient": {
                      "type": "string",
                      "description": "Alamat tujuan pengiriman email. String kosong jika tidak ada alamat yang diketahui untuk orang tersebut: maka tidak ada email yang dapat dikirim dan `preview_token` juga kosong. Teruskan sebagai `email_address` saat Anda mengonfirmasi.",
                      "example": "person@example.com"
                    },
                    "recipient_source": {
                      "type": "string",
                      "enum": [
                        "email_verification",
                        "contact_details",
                        "request",
                        ""
                      ],
                      "description": "Dari mana asal `recipient`. `request`: `email_address` yang Anda teruskan. `email_verification`: alamat yang diverifikasi orang tersebut dalam langkah verifikasi email pada alur. `contact_details`: alamat yang diberikan dalam `contact_details` saat sesi dibuat. Berupa string kosong jika tidak ada alamat.",
                      "example": "email_verification"
                    },
                    "sender": {
                      "type": "string",
                      "description": "Header `From` yang digunakan untuk mengirim email.",
                      "example": "Example App <no-reply@mail.example.com>"
                    },
                    "sender_name": {
                      "type": "string",
                      "description": "Bagian nama tampilan dari `sender`.",
                      "example": "Example App"
                    },
                    "sender_email": {
                      "type": "string",
                      "format": "email",
                      "description": "Bagian alamat dari `sender`.",
                      "example": "no-reply@mail.example.com"
                    },
                    "sender_kind": {
                      "type": "string",
                      "enum": [
                        "customer",
                        "didit"
                      ],
                      "description": "`customer`: email dikirim dari domain pengirim terverifikasi aplikasi Anda (White Label). `didit`: email dikirim dari pengirim Didit sendiri.",
                      "example": "customer"
                    },
                    "subject": {
                      "type": "string",
                      "description": "Baris subjek persis seperti yang dikirimkan.",
                      "example": "Action Required: Complete your verification in Example App"
                    },
                    "html": {
                      "type": "string",
                      "description": "HTML email persis seperti yang dikirim, dengan logonya disematkan sebagai URL data. Render dalam frame sandbox, jangan pernah langsung di DOM aplikasi Anda.",
                      "example": "<!DOCTYPE html><html><body>...</body></html>"
                    },
                    "text": {
                      "type": "string",
                      "description": "Kata-kata email sebagai teks biasa, sebagaimana disimpan dalam utas Pesan orang tersebut, untuk pratinjau ringkas (HTML tetap berupa email yang diterima orang tersebut).",
                      "example": "Almost there\n\nSome steps need to be completed again.\nHere’s what to fix:\n\nhttps://verify.didit.me/session/abc123"
                    },
                    "language": {
                      "type": "string",
                      "description": "Bahasa penulisan email. Bahasa Inggris (`en`) saat `email_language` yang Anda minta tidak tersedia.",
                      "example": "en"
                    },
                    "will_be_sent": {
                      "type": "boolean",
                      "description": "Menentukan apakah mengonfirmasi perubahan dengan `send_email: true` mengirimkan email ini. `false` jika `not_sent_reason` diatur.",
                      "example": true
                    },
                    "not_sent_reason": {
                      "type": "string",
                      "nullable": true,
                      "enum": [
                        "no_user_action",
                        "no_recipient",
                        "sandbox",
                        null
                      ],
                      "description": "Alasan mengapa konfirmasi tidak akan mengirim email, atau `null` jika akan dikirim. `no_user_action`: setiap langkah yang dipilih berjalan tanpa orang tersebut, sehingga pengiriman ulang selesai dengan sendirinya dan tidak ada email yang dikirim. `no_recipient`: tidak ada alamat yang diketahui untuk orang tersebut dan Anda tidak meneruskannya. `sandbox`: sesi sandbox yang penerimanya belum menyetujui pengiriman email sandbox, sehingga pengiriman hanya disimulasikan.",
                      "example": null
                    },
                    "nodes_to_resubmit": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "required": [
                          "node_id",
                          "feature"
                        ],
                        "properties": {
                          "node_id": {
                            "type": "string",
                            "description": "Pengenal node seperti yang muncul dalam definisi alur kerja sesi (misalnya `feature_ocr`, `feature_liveness`).",
                            "example": "feature_ocr"
                          },
                          "feature": {
                            "type": "string",
                            "description": "Tipe fitur dari node. Alias `ID_VERIFICATION`, `POA`, `PHONE`, dan `EMAIL` dinormalisasi di sisi server menjadi `OCR`, `PROOF_OF_ADDRESS`, `PHONE_VERIFICATION`, dan `EMAIL_VERIFICATION`. `KYB_REGISTRY`, `KYB_KEY_PEOPLE`, dan `KYB` lolos validasi skema tetapi selalu ditolak dengan aturan bisnis `400` yang ditunjukkan pada contoh.",
                            "enum": [
                              "OCR",
                              "OCR_BACK",
                              "NFC",
                              "AML",
                              "FACE",
                              "LIVENESS",
                              "FACE_MATCH",
                              "IP_ANALYSIS",
                              "AGE_ESTIMATION",
                              "PROOF_OF_ADDRESS",
                              "PHONE_VERIFICATION",
                              "EMAIL_VERIFICATION",
                              "FACE_SEARCH",
                              "DATABASE_VALIDATION",
                              "QUESTIONNAIRE",
                              "DOCUMENT_AI",
                              "KYB_DOCUMENTS",
                              "ID_VERIFICATION",
                              "POA",
                              "PHONE",
                              "EMAIL",
                              "KYB_REGISTRY",
                              "KYB_KEY_PEOPLE",
                              "KYB",
                              "GEOLOCATION"
                            ],
                            "example": "OCR"
                          }
                        }
                      }
                    },
                    "requires_user_action": {
                      "type": "boolean",
                      "description": "Menentukan apakah setidaknya satu pemeriksaan yang dipilih memerlukan interaksi pengguna. Ini tidak memprediksi hasil akhir alur kerja."
                    },
                    "preview_token": {
                      "type": "string",
                      "description": "Tanda terima yang ditandatangani untuk email persis ini, valid selama 15 menit. Teruskan sebagai `email_preview_token` ke [Perbarui Status Sesi](/id/sessions-api/update-status). String kosong jika tidak ada penerima.",
                      "example": "eyJkaWdlc3QiOiI0ZjJhIn0:1uExAm:Pl3x4mpleS1gnatureValue000000000000000"
                    }
                  }
                },
                "examples": {
                  "Will Be Sent": {
                    "summary": "Penerima default: alamat yang diverifikasi dalam alur",
                    "value": {
                      "recipient": "person@example.com",
                      "recipient_source": "email_verification",
                      "sender": "Example App <no-reply@mail.example.com>",
                      "sender_name": "Example App",
                      "sender_email": "no-reply@mail.example.com",
                      "sender_kind": "customer",
                      "subject": "Action Required: Complete your verification in Example App",
                      "html": "<!DOCTYPE html><html><body>...</body></html>",
                      "language": "en",
                      "will_be_sent": true,
                      "not_sent_reason": null,
                      "nodes_to_resubmit": [
                        {
                          "node_id": "feature_poa_1",
                          "feature": "PROOF_OF_ADDRESS"
                        }
                      ],
                      "requires_user_action": true,
                      "preview_token": "eyJkaWdlc3QiOiI0ZjJhIn0:1uExAm:Pl3x4mpleS1gnatureValue000000000000000"
                    }
                  },
                  "No User Action": {
                    "summary": "Hanya langkah backend yang dipilih, sehingga tidak ada email yang dikirim",
                    "value": {
                      "recipient": "person@example.com",
                      "recipient_source": "contact_details",
                      "sender": "Example App <no-reply@mail.example.com>",
                      "sender_name": "Example App",
                      "sender_email": "no-reply@mail.example.com",
                      "sender_kind": "customer",
                      "subject": "Action Required: Complete your verification in Example App",
                      "html": "<!DOCTYPE html><html><body>...</body></html>",
                      "language": "en",
                      "will_be_sent": false,
                      "not_sent_reason": "no_user_action",
                      "nodes_to_resubmit": [
                        {
                          "node_id": "feature_aml",
                          "feature": "AML"
                        }
                      ],
                      "requires_user_action": false,
                      "preview_token": "eyJkaWdlc3QiOiI0ZjJhIn0:1uExAm:Pl3x4mpleS1gnatureValue000000000000000"
                    }
                  }
                }
              }
            },
            "headers": {
              "Cache-Control": {
                "description": "Selalu `no-store`: pratinjau memuat konten verifikasi dan tidak boleh disimpan dalam cache.",
                "schema": {
                  "type": "string",
                  "example": "no-store"
                }
              }
            }
          },
          "400": {
            "description": "Sesi tidak berada dalam status yang diterima endpoint ini, sudah `Resubmitted`, langkah yang dipilih tidak dapat dikirim ulang, atau suatu kolom tidak valid.",
            "content": {
              "application/json": {
                "examples": {
                  "Wrong Current Status": {
                    "summary": "Sesi tidak berada dalam status yang diterima oleh endpoint ini",
                    "value": {
                      "detail": "Only sessions with status Approved, Declined, In Review, Kyc Expired, Abandoned, Resubmitted can be updated. Current status: In Progress"
                    }
                  },
                  "Already Resubmitted": {
                    "summary": "Sesi sudah Resubmitted",
                    "value": [
                      "The new status is the same as the current status."
                    ]
                  },
                  "Nothing To Resubmit": {
                    "summary": "Pilihan otomatis tidak menemukan langkah yang memerlukan pengiriman ulang",
                    "value": {
                      "nodes_to_resubmit": "No features found that need resubmission. All features are already approved."
                    }
                  },
                  "Invalid Email": {
                    "summary": "email_address bukan alamat email",
                    "value": {
                      "email_address": [
                        "Enter a valid email address."
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Kunci API dengan cakupan terbatas telah kedaluwarsa.",
            "content": {
              "application/json": {
                "examples": {
                  "Expired API Key": {
                    "summary": "Kunci API ber-scope melewati tanggal kedaluwarsanya",
                    "value": {
                      "detail": "This API key has expired."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Kredensial tidak ada, pemanggil tanpa hak istimewa `write:sessions`, kunci API dengan pembatasan cakupan tanpa akses yang dibutuhkan endpoint ini, atau `session_id` milik aplikasi lain.",
            "content": {
              "application/json": {
                "examples": {
                  "Invalid Credentials": {
                    "summary": "x-api-key tidak ada atau tidak valid",
                    "value": {
                      "detail": "Authentication credentials were not provided or are invalid."
                    }
                  },
                  "Missing Privilege": {
                    "summary": "Pemanggil tidak memiliki izin write:sessions",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Scoped Key Without Access": {
                    "summary": "Kunci API ber-scope tanpa akses ini",
                    "value": {
                      "detail": "This API key has no write access to decisions."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Tidak ada sesi KYC atau KYB dengan `session_id` ini.",
            "content": {
              "application/json": {
                "examples": {
                  "Not Found": {
                    "summary": "session_id tidak dikenal",
                    "value": {
                      "detail": "Not found."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Langkah-langkah yang akan diajukan ulang semuanya hanya untuk backend (AML, DATABASE_VALIDATION, IP_ANALYSIS), dan sesi telah diajukan ulang untuk langkah khusus backend dalam 30 detik terakhir, sehingga Update Session Status akan menolak pengajuan ulang. Coba lagi setelah interval di `Retry-After`.",
            "content": {
              "application/json": {
                "examples": {
                  "Backend-only resubmit throttled": {
                    "value": {
                      "detail": "This session was already resubmitted for backend-only features within the last 30 seconds; repeating it cannot change the outcome. Wait before resubmitting again."
                    }
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.preview_resubmission(\n    \"11111111-2222-3333-4444-555555555555\",\n    nodes_to_resubmit=[{\n        \"node_id\": \"feature_poa_1\",\n        \"feature\": \"POA\",\n    }],\n    email_language=\"en\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.previewResubmission(\"11111111-2222-3333-4444-555555555555\", {\n  nodes_to_resubmit: [{\n    node_id: \"feature_poa_1\",\n    feature: \"POA\",\n  }],\n  email_language: \"en\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.PreviewResubmission(ctx, \"11111111-2222-3333-4444-555555555555\", didit.SessionsPreviewResubmissionParams{\n\tNodesToResubmit: didit.Some([]didit.SessionsPreviewResubmissionParamsNodesToResubmit{{\n\t\tNodeID:  \"feature_poa_1\",\n\t\tFeature: \"POA\",\n\t}}),\n\tEmailLanguage: didit.String(\"en\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.List;\nimport me.didit.Didit;\nimport me.didit.types.SessionsPreviewResubmissionParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().previewResubmission(\"11111111-2222-3333-4444-555555555555\", SessionsPreviewResubmissionParams.builder()\n        .nodesToResubmit(List.of(SessionsPreviewResubmissionParams.NodesToResubmit.builder()\n                .nodeId(\"feature_poa_1\")\n                .feature(SessionsPreviewResubmissionParams.NodesToResubmit.Feature.of(\"POA\"))\n                .build()))\n        .emailLanguage(\"en\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->sessions->previewResubmission('11111111-2222-3333-4444-555555555555', [\n    'nodes_to_resubmit' => [[\n        'node_id' => 'feature_poa_1',\n        'feature' => 'POA',\n    ]],\n    'email_language' => 'en',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.preview_resubmission(\n  \"11111111-2222-3333-4444-555555555555\",\n  nodes_to_resubmit: [{\n    node_id: \"feature_poa_1\",\n    feature: \"POA\",\n  }],\n  email_language: \"en\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.PreviewResubmissionAsync(\"11111111-2222-3333-4444-555555555555\", new SessionsPreviewResubmissionParams\n{\n    NodesToResubmit = new SessionsPreviewResubmissionParamsNodesToResubmit[]\n    {\n        new()\n        {\n            NodeId = \"feature_poa_1\",\n            Feature = \"POA\",\n        },\n    },\n    EmailLanguage = \"en\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/cases/routing-rules/{record_uuid}/": {
      "get": {
        "summary": "Ambil aturan perutean",
        "description": "Memerlukan `read:cases` untuk aplikasi yang diminta.",
        "operationId": "retrieve_case_routing_rules",
        "x-didit-sdk": {
          "resource": "cases.routing_rules",
          "method": "retrieve",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Case Assignment"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID organisasi."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID aplikasi."
          },
          {
            "name": "record_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Berhasil",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CaseRoutingRule"
                }
              }
            }
          },
          "400": {
            "description": "Input tidak valid."
          },
          "403": {
            "description": "Izin tidak memadai."
          },
          "404": {
            "description": "Catatan tidak ditemukan dalam aplikasi ini."
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.routing_rules.retrieve(\n    \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.routingRules.retrieve(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.RoutingRules.Retrieve(ctx, \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().routingRules().retrieve(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->cases->routingRules->retrieve('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.routing_rules.retrieve(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.RoutingRules.RetrieveAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      },
      "patch": {
        "summary": "Perbarui aturan perutean",
        "description": "Memerlukan `write:cases` untuk aplikasi yang diminta.",
        "operationId": "update_case_routing_rules",
        "x-didit-sdk": {
          "resource": "cases.routing_rules",
          "method": "update",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Case Assignment"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID organisasi."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID aplikasi."
          },
          {
            "name": "record_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Berhasil",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CaseRoutingRule"
                }
              }
            }
          },
          "400": {
            "description": "Input tidak valid."
          },
          "403": {
            "description": "Izin tidak memadai."
          },
          "404": {
            "description": "Catatan tidak ditemukan dalam aplikasi ini."
          },
          "409": {
            "description": "Aturan perutean telah berubah sejak expected_version. Tinjau aturan terbaru sebelum mencoba lagi."
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CaseRoutingRuleUpdate"
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.routing_rules.update(\n    \"11111111-2222-3333-4444-555555555555\",\n    name=\"your-name\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.routingRules.update(\"11111111-2222-3333-4444-555555555555\", {\n  name: \"your-name\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.RoutingRules.Update(ctx, \"11111111-2222-3333-4444-555555555555\", didit.CaseRoutingRuleUpdate{\n\tName: didit.String(\"your-name\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.CaseRoutingRuleUpdate;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().routingRules().update(\"11111111-2222-3333-4444-555555555555\", CaseRoutingRuleUpdate.builder()\n        .name(\"your-name\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->cases->routingRules->update('11111111-2222-3333-4444-555555555555', [\n    'name' => 'your-name',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.routing_rules.update(\n  \"11111111-2222-3333-4444-555555555555\",\n  name: \"your-name\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.RoutingRules.UpdateAsync(\"11111111-2222-3333-4444-555555555555\", new CaseRoutingRuleUpdate\n{\n    Name = \"your-name\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/case-requests/{request_uuid}/": {
      "get": {
        "operationId": "case_requests_retrieve",
        "x-didit-sdk": {
          "resource": "case_requests",
          "method": "retrieve",
          "auth": "device_token",
          "server": false
        },
        "parameters": [
          {
            "in": "path",
            "name": "request_uuid",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          }
        ],
        "tags": [
          "Case Management"
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CustomerMessagingCaseRequestPublic"
                }
              }
            },
            "description": ""
          },
          "404": {
            "description": "Permintaan atau kasus tidak tersedia untuk pemanggil ini."
          }
        },
        "security": [
          {
            "CaseRequestToken": []
          }
        ],
        "description": "Akses satu permintaan pelanggan menggunakan token khusus permintaannya. Tidak ada temuan kasus privat, data identitas asli, atau alamat penerima yang dikembalikan. Permintaan yang dapat ditindaklanjuti kedaluwarsa setelah tujuh hari. Pembatalan atau penyelesaian kasus menjadikan tautan tidak valid. Respons tidak dapat diubah dan tetap menjadi bukti untuk penilaian peninjau; respons tidak pernah menyetujui atau memperbarui verifikasi sumber."
      },
      "post": {
        "operationId": "case_requests_create",
        "x-didit-sdk": {
          "resource": "case_requests",
          "method": "respond",
          "auth": "device_token",
          "server": false
        },
        "parameters": [
          {
            "in": "path",
            "name": "request_uuid",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          }
        ],
        "tags": [
          "Case Management"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CustomerMessagingCaseCustomerResponseRequest"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/CustomerMessagingCaseCustomerResponseRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CustomerMessagingCaseCustomerResponseResult"
                }
              }
            },
            "description": ""
          },
          "404": {
            "description": "Permintaan atau kasus tidak tersedia untuk pemanggil ini."
          },
          "400": {
            "description": "Input tidak valid, tujuan tidak didukung, kontak terverifikasi tidak tersedia, atau respons yang sudah ada tidak dapat diubah."
          },
          "409": {
            "description": "Pratinjau telah berubah atau kedaluwarsa. Tampilkan pratinjau lagi sebelum mengonfirmasi."
          }
        },
        "security": [
          {
            "CaseRequestToken": []
          }
        ],
        "description": "Akses satu permintaan pelanggan menggunakan token khusus permintaannya. Tidak ada temuan kasus privat, data identitas asli, atau alamat penerima yang dikembalikan. Permintaan yang dapat ditindaklanjuti kedaluwarsa setelah tujuh hari. Pembatalan atau penyelesaian kasus menjadikan tautan tidak valid. Respons tidak dapat diubah dan tetap menjadi bukti untuk penilaian peninjau; respons tidak pernah menyetujui atau memperbarui verifikasi sumber."
      }
    },
    "/v3/fraud/checks/plan/": {
      "post": {
        "operationId": "plan_create",
        "x-didit-sdk": {
          "resource": "fraud_checks",
          "method": "plan",
          "auth": "api_key",
          "server": true
        },
        "description": "Validasi pemeriksaan yang dipilih dan perkirakan harganya tanpa mengeksekusi, membuat sesi, atau penagihan.",
        "summary": "Rencanakan Pemeriksaan Penipuan",
        "tags": [
          "Fraud Check"
        ],
        "requestBody": {
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/FraudCheckRequestRequest"
              }
            },
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/FraudCheckRequestRequest"
              },
              "example": {
                "client_reference": "review-attempt-001",
                "subject": {
                  "identifiers": [
                    {
                      "type": "email",
                      "value": "applicant@example.com"
                    }
                  ],
                  "attributes": {
                    "first_name": "Alex",
                    "last_name": "Example"
                  }
                },
                "checks": {
                  "include": [
                    "networks_same_org",
                    "networks_cross_org",
                    "email_risk"
                  ]
                }
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/FraudCheckRequestRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FraudCheckPlan"
                }
              }
            },
            "description": ""
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FraudBadRequestErrorMessage"
                }
              }
            },
            "description": ""
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          },
          {
            "BearerAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.fraud_checks.plan(\n    client_reference=\"review-attempt-001\",\n    subject={\n        \"identifiers\": [{\n            \"type\": \"email\",\n            \"value\": \"applicant@example.com\",\n        }],\n        \"attributes\": {\n            \"first_name\": \"Alex\",\n            \"last_name\": \"Example\",\n        },\n    },\n    checks={\n        \"include\": [\"networks_same_org\", \"networks_cross_org\", \"email_risk\"],\n    },\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.fraudChecks.plan({\n  client_reference: \"review-attempt-001\",\n  subject: {\n    identifiers: [{\n      type: \"email\",\n      value: \"applicant@example.com\",\n    }],\n    attributes: {\n      first_name: \"Alex\",\n      last_name: \"Example\",\n    },\n  },\n  checks: {\n    include: [\"networks_same_org\", \"networks_cross_org\", \"email_risk\"],\n  },\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.FraudChecks.Plan(ctx, didit.FraudCheckRequestRequest{\n\tClientReference: didit.String(\"review-attempt-001\"),\n\tSubject: didit.FraudCheckSubjectRequest{\n\t\tIdentifiers: []didit.FraudCheckIdentifierRequest{{\n\t\t\tType:  didit.FraudTypeEnum(\"email\"),\n\t\t\tValue: \"applicant@example.com\",\n\t\t}},\n\t\tAttributes: didit.Some(didit.FraudCheckAttributesRequest{\n\t\t\tFirstName: didit.String(\"Alex\"),\n\t\t\tLastName:  didit.String(\"Example\"),\n\t\t}),\n\t},\n\tChecks: didit.Some(didit.FraudCheckModuleSelectionRequest{\n\t\tInclude: didit.Some([]didit.FraudExcludeEnum{didit.FraudExcludeEnum(\"networks_same_org\"), didit.FraudExcludeEnum(\"networks_cross_org\"), didit.FraudExcludeEnum(\"email_risk\")}),\n\t}),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.List;\nimport me.didit.Didit;\nimport me.didit.types.FraudCheckAttributesRequest;\nimport me.didit.types.FraudCheckIdentifierRequest;\nimport me.didit.types.FraudCheckModuleSelectionRequest;\nimport me.didit.types.FraudCheckRequestRequest;\nimport me.didit.types.FraudCheckSubjectRequest;\nimport me.didit.types.FraudExcludeEnum;\nimport me.didit.types.FraudTypeEnum;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.fraudChecks().plan(FraudCheckRequestRequest.builder()\n        .clientReference(\"review-attempt-001\")\n        .subject(FraudCheckSubjectRequest.builder()\n                .identifiers(List.of(FraudCheckIdentifierRequest.builder()\n                        .type(FraudTypeEnum.of(\"email\"))\n                        .value(\"applicant@example.com\")\n                        .build()))\n                .attributes(FraudCheckAttributesRequest.builder()\n                        .firstName(\"Alex\")\n                        .lastName(\"Example\")\n                        .build())\n                .build())\n        .checks(FraudCheckModuleSelectionRequest.builder()\n                .include(List.of(FraudExcludeEnum.of(\"networks_same_org\"), FraudExcludeEnum.of(\"networks_cross_org\"), FraudExcludeEnum.of(\"email_risk\")))\n                .build())\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->fraudChecks->plan([\n    'client_reference' => 'review-attempt-001',\n    'subject' => [\n        'identifiers' => [[\n            'type' => 'email',\n            'value' => 'applicant@example.com',\n        ]],\n        'attributes' => [\n            'first_name' => 'Alex',\n            'last_name' => 'Example',\n        ],\n    ],\n    'checks' => [\n        'include' => ['networks_same_org', 'networks_cross_org', 'email_risk'],\n    ],\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.fraud_checks.plan(\n  client_reference: \"review-attempt-001\",\n  subject: {\n    identifiers: [{\n      type: \"email\",\n      value: \"applicant@example.com\",\n    }],\n    attributes: {\n      first_name: \"Alex\",\n      last_name: \"Example\",\n    },\n  },\n  checks: {\n    include: [\"networks_same_org\", \"networks_cross_org\", \"email_risk\"],\n  }\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.FraudChecks.PlanAsync(new FraudCheckRequestRequest\n{\n    ClientReference = \"review-attempt-001\",\n    Subject = new()\n    {\n        Identifiers = new FraudCheckIdentifierRequest[]\n        {\n            new()\n            {\n                Type = \"email\",\n                Value = \"applicant@example.com\",\n            },\n        },\n        Attributes = new FraudCheckAttributesRequest\n        {\n            FirstName = \"Alex\",\n            LastName = \"Example\",\n        },\n    },\n    Checks = new FraudCheckModuleSelectionRequest\n    {\n        Include = new FraudExcludeEnum[] { \"networks_same_org\", \"networks_cross_org\", \"email_risk\" },\n    },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/cases/routing-rules/": {
      "get": {
        "summary": "Mencantumkan aturan perutean",
        "description": "Memerlukan `list:cases` untuk aplikasi yang diminta.",
        "operationId": "list_case_routing_rules",
        "x-didit-sdk": {
          "resource": "cases.routing_rules",
          "method": "list",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Case Assignment"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID organisasi."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID aplikasi."
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 50
            }
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "maximum": 1000000,
              "default": 0
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Berhasil",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "results": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/CaseRoutingRule"
                      }
                    },
                    "count": {
                      "type": "integer",
                      "description": "Jumlah yang cocok, dibatasi maksimal 100. Gunakan next untuk melanjutkan setelah batas tersebut."
                    },
                    "next": {
                      "type": "string",
                      "nullable": true
                    },
                    "previous": {
                      "type": "string",
                      "nullable": true
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Input tidak valid."
          },
          "403": {
            "description": "Izin tidak memadai."
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nfor item in client.cases.routing_rules.list():\n    print(item)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nfor await (const item of didit.cases.routingRules.list()) {\n  console.log(item);\n}"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\niter := client.Cases.RoutingRules.ListAutoPaging(ctx, didit.CasesRoutingRulesListParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nfor (var item : client.cases().routingRules().list()) {\n    System.out.println(item);\n}"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\nforeach ($didit->cases->routingRules->list() as $item) {\n    print_r($item->toArray());\n}"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\ndidit.cases.routing_rules.list.auto_paging_each do |item|\n  puts item.to_h\nend"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.Cases.RoutingRules.ListAsync())\n{\n    Console.WriteLine(JsonSerializer.Serialize(item));\n}"
          }
        ]
      },
      "post": {
        "summary": "Buat aturan perutean",
        "description": "Memerlukan `write:cases` untuk aplikasi yang diminta. Atur publish=false untuk membuat draf yang belum dipublikasikan; Publish membuat versi langsung pertamanya. Membuang draf yang belum pernah dipublikasikan akan menghapusnya.",
        "operationId": "create_case_routing_rules",
        "x-didit-sdk": {
          "resource": "cases.routing_rules",
          "method": "create",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Case Assignment"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID organisasi."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID aplikasi."
          }
        ],
        "responses": {
          "201": {
            "description": "Berhasil",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CaseRoutingRule"
                }
              }
            }
          },
          "400": {
            "description": "Input tidak valid."
          },
          "403": {
            "description": "Izin tidak memadai."
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CaseRoutingRuleCreate"
              },
              "example": {
                "name": "AML screening alerts",
                "conditions": [
                  {
                    "field": "source",
                    "operator": "equals",
                    "value": "AML_SCREENING"
                  }
                ],
                "blueprint": "b1de0000-0000-4000-8000-000000000002"
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.routing_rules.create(\n    name=\"AML screening alerts\",\n    conditions=[{\n        \"field\": \"source\",\n        \"operator\": \"equals\",\n        \"value\": \"AML_SCREENING\",\n    }],\n    blueprint=\"b1de0000-0000-4000-8000-000000000002\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.routingRules.create({\n  name: \"AML screening alerts\",\n  conditions: [{\n    field: \"source\",\n    operator: \"equals\",\n    value: \"AML_SCREENING\",\n  }],\n  blueprint: \"b1de0000-0000-4000-8000-000000000002\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.RoutingRules.Create(ctx, didit.CaseRoutingRuleCreate{\n\tName: \"AML screening alerts\",\n\tConditions: []didit.CaseRoutingConditionParam{{\n\t\tField:    \"source\",\n\t\tOperator: \"equals\",\n\t\tValue:    \"AML_SCREENING\",\n\t}},\n\tBlueprint: \"b1de0000-0000-4000-8000-000000000002\",\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.List;\nimport me.didit.Didit;\nimport me.didit.types.CaseRoutingCondition;\nimport me.didit.types.CaseRoutingRuleCreate;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().routingRules().create(CaseRoutingRuleCreate.builder()\n        .name(\"AML screening alerts\")\n        .conditions(List.of(CaseRoutingCondition.builder()\n                .field(CaseRoutingCondition.Field.of(\"source\"))\n                .operator(CaseRoutingCondition.Operator.of(\"equals\"))\n                .value(CaseRoutingCondition.Value.ofString(\"AML_SCREENING\"))\n                .build()))\n        .blueprint(\"b1de0000-0000-4000-8000-000000000002\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->cases->routingRules->create([\n    'name' => 'AML screening alerts',\n    'conditions' => [[\n        'field' => 'source',\n        'operator' => 'equals',\n        'value' => 'AML_SCREENING',\n    ]],\n    'blueprint' => 'b1de0000-0000-4000-8000-000000000002',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.routing_rules.create(\n  name: \"AML screening alerts\",\n  conditions: [{\n    field: \"source\",\n    operator: \"equals\",\n    value: \"AML_SCREENING\",\n  }],\n  blueprint: \"b1de0000-0000-4000-8000-000000000002\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.RoutingRules.CreateAsync(new CaseRoutingRuleCreate\n{\n    Name = \"AML screening alerts\",\n    Conditions = new CaseRoutingCondition[]\n    {\n        new()\n        {\n            Field = \"source\",\n            Operator = \"equals\",\n            Value = \"AML_SCREENING\",\n        },\n    },\n    Blueprint = \"b1de0000-0000-4000-8000-000000000002\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/cases/routing-rules/{record_uuid}/publish/": {
      "post": {
        "operationId": "publish_case_routing_rule",
        "x-didit-sdk": {
          "resource": "cases.routing_rules",
          "method": "publish",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "parameters": [
          {
            "in": "path",
            "name": "organization_id",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          },
          {
            "in": "path",
            "name": "application_id",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          },
          {
            "in": "path",
            "name": "record_uuid",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          }
        ],
        "tags": [
          "Case Assignment"
        ],
        "requestBody": {
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/RoutingPublicationPolicyDraftPreconditionRequest"
              }
            },
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RoutingPublicationPolicyDraftPreconditionRequest"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/RoutingPublicationPolicyDraftPreconditionRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RoutingPublicationCaseRoutingRule"
                }
              }
            },
            "description": ""
          },
          "403": {
            "description": "Akses kasus diperlukan."
          },
          "409": {
            "description": "Versi yang dipublikasikan atau revisi draf telah berubah. Muat ulang sebelum mencoba lagi."
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.routing_rules.publish(\n    \"11111111-2222-3333-4444-555555555555\",\n    expected_version=0,\n    expected_revision=\"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.routingRules.publish(\"11111111-2222-3333-4444-555555555555\", {\n  expected_version: 0,\n  expected_revision: \"11111111-2222-3333-4444-555555555555\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.RoutingRules.Publish(ctx, \"11111111-2222-3333-4444-555555555555\", didit.RoutingPublicationPolicyDraftPreconditionRequest{\n\tExpectedVersion:  0,\n\tExpectedRevision: didit.String(\"11111111-2222-3333-4444-555555555555\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.RoutingPublicationPolicyDraftPreconditionRequest;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().routingRules().publish(\"11111111-2222-3333-4444-555555555555\", RoutingPublicationPolicyDraftPreconditionRequest.builder()\n        .expectedVersion(0L)\n        .expectedRevision(\"11111111-2222-3333-4444-555555555555\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->cases->routingRules->publish('11111111-2222-3333-4444-555555555555', [\n    'expected_version' => 0,\n    'expected_revision' => '11111111-2222-3333-4444-555555555555',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.routing_rules.publish(\n  \"11111111-2222-3333-4444-555555555555\",\n  expected_version: 0,\n  expected_revision: \"11111111-2222-3333-4444-555555555555\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.RoutingRules.PublishAsync(\"11111111-2222-3333-4444-555555555555\", new RoutingPublicationPolicyDraftPreconditionRequest\n{\n    ExpectedVersion = 0,\n    ExpectedRevision = \"11111111-2222-3333-4444-555555555555\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/cases/blueprints/{blueprint_uuid}/publish/": {
      "post": {
        "operationId": "publish_case_blueprint",
        "x-didit-sdk": {
          "resource": "cases.blueprints",
          "method": "publish",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "parameters": [
          {
            "in": "path",
            "name": "organization_id",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          },
          {
            "in": "path",
            "name": "application_id",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          },
          {
            "in": "path",
            "name": "blueprint_uuid",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          }
        ],
        "tags": [
          "Case Management"
        ],
        "requestBody": {
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/CasePublicationPolicyDraftPreconditionRequest"
              }
            },
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CasePublicationPolicyDraftPreconditionRequest"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/CasePublicationPolicyDraftPreconditionRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CasePublicationCaseBlueprint"
                }
              }
            },
            "description": ""
          },
          "409": {
            "description": "Versi yang dipublikasikan atau revisi draf yang disimpan telah berubah. Muat ulang sebelum mencoba lagi."
          },
          "403": {
            "description": "Izin kasus yang diperlukan tidak ada."
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.blueprints.publish(\n    \"11111111-2222-3333-4444-555555555555\",\n    expected_version=0,\n    expected_revision=\"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.blueprints.publish(\"11111111-2222-3333-4444-555555555555\", {\n  expected_version: 0,\n  expected_revision: \"11111111-2222-3333-4444-555555555555\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.Blueprints.Publish(ctx, \"11111111-2222-3333-4444-555555555555\", didit.CasePublicationPolicyDraftPreconditionRequest{\n\tExpectedVersion:  0,\n\tExpectedRevision: didit.String(\"11111111-2222-3333-4444-555555555555\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.CasePublicationPolicyDraftPreconditionRequest;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().blueprints().publish(\"11111111-2222-3333-4444-555555555555\", CasePublicationPolicyDraftPreconditionRequest.builder()\n        .expectedVersion(0L)\n        .expectedRevision(\"11111111-2222-3333-4444-555555555555\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->cases->blueprints->publish('11111111-2222-3333-4444-555555555555', [\n    'expected_version' => 0,\n    'expected_revision' => '11111111-2222-3333-4444-555555555555',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.blueprints.publish(\n  \"11111111-2222-3333-4444-555555555555\",\n  expected_version: 0,\n  expected_revision: \"11111111-2222-3333-4444-555555555555\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.Blueprints.PublishAsync(\"11111111-2222-3333-4444-555555555555\", new CasePublicationPolicyDraftPreconditionRequest\n{\n    ExpectedVersion = 0,\n    ExpectedRevision = \"11111111-2222-3333-4444-555555555555\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/cases/{case_uuid}/requests/preview/": {
      "post": {
        "operationId": "organization_application_cases_requests_preview_create",
        "x-didit-sdk": {
          "resource": "cases.requests",
          "method": "preview",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "parameters": [
          {
            "in": "path",
            "name": "organization_id",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          },
          {
            "in": "path",
            "name": "application_id",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          },
          {
            "in": "path",
            "name": "case_uuid",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          }
        ],
        "tags": [
          "Case Management"
        ],
        "requestBody": {
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/CustomerMessagingCaseRequestPreviewRequest"
              }
            },
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CustomerMessagingCaseRequestPreviewRequest"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/CustomerMessagingCaseRequestPreviewRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CustomerMessagingCaseRequestPreviewResponse"
                }
              }
            },
            "description": ""
          },
          "404": {
            "description": "Permintaan atau kasus tidak tersedia untuk pemanggil ini."
          },
          "403": {
            "description": "Pemanggil tidak memiliki izin kasus yang diperlukan."
          },
          "400": {
            "description": "Input tidak valid, tujuan tidak didukung, kontak terverifikasi tidak tersedia, atau respons yang sudah ada tidak dapat diubah."
          },
          "409": {
            "description": "Pratinjau telah berubah atau kedaluwarsa. Tampilkan pratinjau lagi sebelum mengonfirmasi."
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "description": "Render email produksi tanpa mengirim atau mengubah kasus. Mengembalikan penerima, pengirim, subjek, isi yang tepat, dan preview_token yang telah ditandatangani. Kirimkan contact_id, purpose, language, request_id, expires_at, dan preview_token yang sama untuk mengonfirmasi dalam waktu 15 menit.",
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.requests.preview(\n    \"11111111-2222-3333-4444-555555555555\",\n    contact_id=\"11111111-2222-3333-4444-555555555555\",\n    purpose=\"identity_document\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.requests.preview(\"11111111-2222-3333-4444-555555555555\", {\n  contact_id: \"11111111-2222-3333-4444-555555555555\",\n  purpose: \"identity_document\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.Requests.Preview(ctx, \"11111111-2222-3333-4444-555555555555\", didit.CustomerMessagingCaseRequestPreviewRequest{\n\tContactID: \"11111111-2222-3333-4444-555555555555\",\n\tPurpose:   didit.CustomerMessagingPurposeEnum(\"identity_document\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.CustomerMessagingCaseRequestPreviewRequest;\nimport me.didit.types.CustomerMessagingPurposeEnum;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().requests().preview(\"11111111-2222-3333-4444-555555555555\", CustomerMessagingCaseRequestPreviewRequest.builder()\n        .contactId(\"11111111-2222-3333-4444-555555555555\")\n        .purpose(CustomerMessagingPurposeEnum.of(\"identity_document\"))\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->cases->requests->preview('11111111-2222-3333-4444-555555555555', [\n    'contact_id' => '11111111-2222-3333-4444-555555555555',\n    'purpose' => 'identity_document',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.requests.preview(\n  \"11111111-2222-3333-4444-555555555555\",\n  contact_id: \"11111111-2222-3333-4444-555555555555\",\n  purpose: \"identity_document\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.Requests.PreviewAsync(\"11111111-2222-3333-4444-555555555555\", new CustomerMessagingCaseRequestPreviewRequest\n{\n    ContactId = \"11111111-2222-3333-4444-555555555555\",\n    Purpose = \"identity_document\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/cases/{case_uuid}/action-receipts/": {
      "get": {
        "operationId": "action_receipts_retrieve",
        "x-didit-sdk": {
          "resource": "cases",
          "method": "list_action_receipts",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "parameters": [
          {
            "in": "path",
            "name": "organization_id",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          },
          {
            "in": "path",
            "name": "application_id",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          },
          {
            "in": "path",
            "name": "case_uuid",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          },
          {
            "in": "query",
            "name": "offset",
            "schema": {
              "type": "integer",
              "maximum": 1000000,
              "minimum": 0,
              "default": 0
            }
          }
        ],
        "tags": [
          "Case Management"
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CaseActionCaseActionReceiptPage"
                }
              }
            },
            "description": ""
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "description": "Mencantumkan daftar tanda terima tindakan subjek, yang terbaru lebih dahulu, dengan paling banyak 20 hasil per halaman. Gunakan next_offset untuk halaman berikutnya. Teks catatan input tidak ditampilkan dalam riwayat.",
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.list_action_receipts(\n    \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.listActionReceipts(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.ListActionReceipts(ctx, \"11111111-2222-3333-4444-555555555555\", didit.CasesListActionReceiptsParams{})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().listActionReceipts(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->cases->listActionReceipts('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.list_action_receipts(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.ListActionReceiptsAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/networks/{network_uuid}/notes/{note_uuid}/": {
      "delete": {
        "operationId": "delete_network_note",
        "x-didit-sdk": {
          "resource": "networks.notes",
          "method": "delete",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Networks"
        ],
        "summary": "Hapus catatan jaringan Anda",
        "description": "Memerlukan write:networks dan penulis catatan yang terautentikasi. Penghapusan tidak dapat dibatalkan. Data akun dan verifikasi yang terhubung tidak terpengaruh.",
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID organisasi."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID aplikasi."
          },
          {
            "name": "network_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID jaringan."
          },
          {
            "name": "note_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "Authorization",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Token akses pengguna konsol dalam format Bearer <token>."
          }
        ],
        "responses": {
          "204": {
            "description": "Catatan dihapus."
          },
          "401": {
            "description": "Autentikasi diperlukan."
          },
          "403": {
            "description": "Izin atau akses Networks tidak ada."
          },
          "404": {
            "description": "Jaringan atau catatan tidak terlihat oleh aplikasi ini."
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\n# Also needs a console user's access token.\nclient = Didit()\n\nclient.networks.notes.delete(\n    \"11111111-2222-3333-4444-555555555555\",\n    \"11111111-2222-3333-4444-555555555555\",\n    extra_headers={\"Authorization\": \"Bearer YOUR_CONSOLE_USER_TOKEN\"},\n)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n// Also needs a console user's access token.\nconst didit = new Didit({\n  fetch: (url, init) => {\n    const headers = new Headers(init?.headers);\n    headers.set(\"Authorization\", \"Bearer YOUR_CONSOLE_USER_TOKEN\");\n    return fetch(url, { ...init, headers });\n  },\n});\n\nawait didit.networks.notes.delete(\n  \"11111111-2222-3333-4444-555555555555\",\n  \"11111111-2222-3333-4444-555555555555\",\n);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n// Also needs a console user's access token.\nclient := didit.NewClient()\n\nif err := client.Networks.Notes.Delete(ctx, \"11111111-2222-3333-4444-555555555555\", \"11111111-2222-3333-4444-555555555555\", didit.NetworksNotesDeleteParams{\n\tAuthorization: \"Bearer YOUR_CONSOLE_USER_TOKEN\",\n}); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.core.RequestOptions;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n// Also needs a console user's access token.\nDidit client = new Didit();\n\nclient.networks().notes().delete(\"11111111-2222-3333-4444-555555555555\", \"11111111-2222-3333-4444-555555555555\", RequestOptions.builder()\n        .header(\"Authorization\", \"Bearer YOUR_CONSOLE_USER_TOKEN\")\n        .build());"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n// Also needs a console user's access token.\n$didit = new DiditClient();\n\n$didit->networks->notes->delete('11111111-2222-3333-4444-555555555555', '11111111-2222-3333-4444-555555555555', [\n    'authorization' => 'Bearer YOUR_CONSOLE_USER_TOKEN',\n]);"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\n# Also needs a console user's access token.\ndidit = Didit::Client.new\n\ndidit.networks.notes.delete(\n  \"11111111-2222-3333-4444-555555555555\",\n  \"11111111-2222-3333-4444-555555555555\",\n  request_options: { extra_headers: { \"Authorization\" => \"Bearer YOUR_CONSOLE_USER_TOKEN\" } }\n)"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Collections.Generic;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n// Also needs a console user's access token.\nusing var client = new DiditClient();\n\nawait client.Networks.Notes.DeleteAsync(\"11111111-2222-3333-4444-555555555555\", \"11111111-2222-3333-4444-555555555555\", requestOptions: new RequestOptions\n{\n    Headers = new Dictionary<string, string>\n    {\n        [\"Authorization\"] = \"Bearer YOUR_CONSOLE_USER_TOKEN\",\n    },\n});"
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/cases/{case_uuid}/action-receipts/{receipt_uuid}/retry/": {
      "post": {
        "operationId": "action_receipts_retry_create",
        "x-didit-sdk": {
          "resource": "cases",
          "method": "retry_action_receipt",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "parameters": [
          {
            "in": "path",
            "name": "organization_id",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          },
          {
            "in": "path",
            "name": "application_id",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          },
          {
            "in": "path",
            "name": "case_uuid",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          },
          {
            "in": "path",
            "name": "receipt_uuid",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          }
        ],
        "tags": [
          "Case Management"
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CaseActionCaseActionReceipt"
                }
              }
            },
            "description": ""
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "description": "Coba lagi hanya tindakan subjek yang gagal ini menggunakan input yang tersimpan. Izin tulis saat ini diperiksa. Tindakan yang telah diterapkan mengembalikan tanda terima tanpa dieksekusi lagi. Penutupan kasus bersifat independen.",
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.retry_action_receipt(\n    \"11111111-2222-3333-4444-555555555555\",\n    \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.retryActionReceipt(\n  \"11111111-2222-3333-4444-555555555555\",\n  \"11111111-2222-3333-4444-555555555555\",\n);\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.RetryActionReceipt(ctx, \"11111111-2222-3333-4444-555555555555\", \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().retryActionReceipt(\"11111111-2222-3333-4444-555555555555\", \"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->cases->retryActionReceipt('11111111-2222-3333-4444-555555555555', '11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.retry_action_receipt(\n  \"11111111-2222-3333-4444-555555555555\",\n  \"11111111-2222-3333-4444-555555555555\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.RetryActionReceiptAsync(\"11111111-2222-3333-4444-555555555555\", \"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/cases/blueprints/{blueprint_uuid}/draft/": {
      "get": {
        "operationId": "get_case_blueprint_draft",
        "x-didit-sdk": {
          "resource": "cases.blueprints",
          "method": "retrieve_draft",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "parameters": [
          {
            "in": "path",
            "name": "organization_id",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          },
          {
            "in": "path",
            "name": "application_id",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          },
          {
            "in": "path",
            "name": "blueprint_uuid",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          }
        ],
        "tags": [
          "Case Management"
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CasePublicationPolicyDraftResponse"
                }
              }
            },
            "description": ""
          },
          "403": {
            "description": "Izin kasus yang diperlukan tidak ada."
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.blueprints.retrieve_draft(\n    \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.blueprints.retrieveDraft(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.Blueprints.RetrieveDraft(ctx, \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().blueprints().retrieveDraft(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->cases->blueprints->retrieveDraft('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.blueprints.retrieve_draft(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.Blueprints.RetrieveDraftAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      },
      "put": {
        "operationId": "save_case_blueprint_draft",
        "x-didit-sdk": {
          "resource": "cases.blueprints",
          "method": "save_draft",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "parameters": [
          {
            "in": "path",
            "name": "organization_id",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          },
          {
            "in": "path",
            "name": "application_id",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          },
          {
            "in": "path",
            "name": "blueprint_uuid",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          }
        ],
        "tags": [
          "Case Management"
        ],
        "requestBody": {
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/CasePublicationPolicyDraftWriteRequest"
              }
            },
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CasePublicationPolicyDraftWriteRequest"
              },
              "example": {
                "expected_version": 1,
                "expected_revision": "4e5f0000-0000-4000-8000-000000000003",
                "changes": {
                  "max_active_cases": 20
                }
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/CasePublicationPolicyDraftWriteRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CasePublicationPolicyDraft"
                }
              }
            },
            "description": ""
          },
          "409": {
            "description": "Versi yang dipublikasikan atau revisi draf yang disimpan telah berubah. Muat ulang sebelum mencoba lagi."
          },
          "403": {
            "description": "Izin kasus yang diperlukan tidak ada."
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.blueprints.save_draft(\n    \"11111111-2222-3333-4444-555555555555\",\n    expected_version=1,\n    expected_revision=\"4e5f0000-0000-4000-8000-000000000003\",\n    changes={\"max_active_cases\": 20},\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.blueprints.saveDraft(\"11111111-2222-3333-4444-555555555555\", {\n  expected_version: 1,\n  expected_revision: \"4e5f0000-0000-4000-8000-000000000003\",\n  changes: { max_active_cases: 20 },\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.Blueprints.SaveDraft(ctx, \"11111111-2222-3333-4444-555555555555\", didit.CasePublicationPolicyDraftWriteRequest{\n\tExpectedVersion:  1,\n\tExpectedRevision: didit.String(\"4e5f0000-0000-4000-8000-000000000003\"),\n\tChanges:          map[string]any{\"max_active_cases\": 20},\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.CasePublicationPolicyDraftWriteRequest;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().blueprints().saveDraft(\"11111111-2222-3333-4444-555555555555\", CasePublicationPolicyDraftWriteRequest.builder()\n        .expectedVersion(1L)\n        .expectedRevision(\"4e5f0000-0000-4000-8000-000000000003\")\n        .changes(Map.of(\"max_active_cases\", 20))\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->cases->blueprints->saveDraft('11111111-2222-3333-4444-555555555555', [\n    'expected_version' => 1,\n    'expected_revision' => '4e5f0000-0000-4000-8000-000000000003',\n    'changes' => ['max_active_cases' => 20],\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.blueprints.save_draft(\n  \"11111111-2222-3333-4444-555555555555\",\n  expected_version: 1,\n  expected_revision: \"4e5f0000-0000-4000-8000-000000000003\",\n  changes: { max_active_cases: 20 }\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.Blueprints.SaveDraftAsync(\"11111111-2222-3333-4444-555555555555\", new CasePublicationPolicyDraftWriteRequest\n{\n    ExpectedVersion = 1,\n    ExpectedRevision = \"4e5f0000-0000-4000-8000-000000000003\",\n    Changes = new Dictionary<string, object> { [\"max_active_cases\"] = 20 },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      },
      "delete": {
        "operationId": "discard_case_blueprint_draft",
        "x-didit-sdk": {
          "resource": "cases.blueprints",
          "method": "discard_draft",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "parameters": [
          {
            "in": "path",
            "name": "organization_id",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          },
          {
            "in": "path",
            "name": "application_id",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          },
          {
            "in": "path",
            "name": "blueprint_uuid",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          }
        ],
        "tags": [
          "Case Management"
        ],
        "responses": {
          "204": {
            "description": "Tidak ada body respons"
          },
          "409": {
            "description": "Versi yang dipublikasikan atau revisi draf yang disimpan telah berubah. Muat ulang sebelum mencoba lagi."
          },
          "403": {
            "description": "Izin kasus yang diperlukan tidak ada."
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CasePublicationPolicyDraftPreconditionRequest"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nclient.cases.blueprints.discard_draft(\n    \"11111111-2222-3333-4444-555555555555\",\n    expected_version=0,\n    expected_revision=\"11111111-2222-3333-4444-555555555555\",\n)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nawait didit.cases.blueprints.discardDraft(\"11111111-2222-3333-4444-555555555555\", {\n  expected_version: 0,\n  expected_revision: \"11111111-2222-3333-4444-555555555555\",\n});"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nif err := client.Cases.Blueprints.DiscardDraft(ctx, \"11111111-2222-3333-4444-555555555555\", didit.CasePublicationPolicyDraftPreconditionRequest{\n\tExpectedVersion:  0,\n\tExpectedRevision: didit.String(\"11111111-2222-3333-4444-555555555555\"),\n}); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.CasePublicationPolicyDraftPreconditionRequest;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nclient.cases().blueprints().discardDraft(\"11111111-2222-3333-4444-555555555555\", CasePublicationPolicyDraftPreconditionRequest.builder()\n        .expectedVersion(0L)\n        .expectedRevision(\"11111111-2222-3333-4444-555555555555\")\n        .build());"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$didit->cases->blueprints->discardDraft('11111111-2222-3333-4444-555555555555', [\n    'expected_version' => 0,\n    'expected_revision' => '11111111-2222-3333-4444-555555555555',\n]);"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\ndidit.cases.blueprints.discard_draft(\n  \"11111111-2222-3333-4444-555555555555\",\n  expected_version: 0,\n  expected_revision: \"11111111-2222-3333-4444-555555555555\"\n)"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nawait client.Cases.Blueprints.DiscardDraftAsync(\"11111111-2222-3333-4444-555555555555\", new CasePublicationPolicyDraftPreconditionRequest\n{\n    ExpectedVersion = 0,\n    ExpectedRevision = \"11111111-2222-3333-4444-555555555555\",\n});"
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/cases/teams/{record_uuid}/": {
      "get": {
        "summary": "Ambil tim peninjau",
        "description": "Memerlukan `read:cases` untuk aplikasi yang diminta.",
        "operationId": "retrieve_case_teams",
        "x-didit-sdk": {
          "resource": "cases.teams",
          "method": "retrieve",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Case Assignment"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID organisasi."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID aplikasi."
          },
          {
            "name": "record_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Berhasil",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CaseReviewTeam"
                }
              }
            }
          },
          "400": {
            "description": "Input tidak valid."
          },
          "403": {
            "description": "Izin tidak memadai."
          },
          "404": {
            "description": "Catatan tidak ditemukan dalam aplikasi ini."
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.teams.retrieve(\n    \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.teams.retrieve(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.Teams.Retrieve(ctx, \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().teams().retrieve(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->cases->teams->retrieve('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.teams.retrieve(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.Teams.RetrieveAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      },
      "patch": {
        "summary": "Perbarui tim peninjau",
        "description": "Memerlukan `write:cases` untuk aplikasi yang diminta.",
        "operationId": "update_case_teams",
        "x-didit-sdk": {
          "resource": "cases.teams",
          "method": "update",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Case Assignment"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID organisasi."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID aplikasi."
          },
          {
            "name": "record_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Berhasil",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CaseReviewTeam"
                }
              }
            }
          },
          "400": {
            "description": "Input tidak valid."
          },
          "403": {
            "description": "Izin tidak memadai."
          },
          "404": {
            "description": "Catatan tidak ditemukan dalam aplikasi ini."
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CaseReviewTeamUpdate"
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.teams.update(\n    \"11111111-2222-3333-4444-555555555555\",\n    name=\"your-name\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.teams.update(\"11111111-2222-3333-4444-555555555555\", {\n  name: \"your-name\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.Teams.Update(ctx, \"11111111-2222-3333-4444-555555555555\", didit.CaseReviewTeamUpdate{\n\tName: didit.String(\"your-name\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.CaseReviewTeamUpdate;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().teams().update(\"11111111-2222-3333-4444-555555555555\", CaseReviewTeamUpdate.builder()\n        .name(\"your-name\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->cases->teams->update('11111111-2222-3333-4444-555555555555', [\n    'name' => 'your-name',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.teams.update(\n  \"11111111-2222-3333-4444-555555555555\",\n  name: \"your-name\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.Teams.UpdateAsync(\"11111111-2222-3333-4444-555555555555\", new CaseReviewTeamUpdate\n{\n    Name = \"your-name\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/networks/{network_uuid}/report/": {
      "get": {
        "operationId": "download_network_report",
        "x-didit-sdk": {
          "resource": "networks",
          "method": "download_report",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Networks"
        ],
        "summary": "Unduh laporan bukti jaringan",
        "description": "Unduh PDF dari jaringan organisasi saat ini, koneksi akun yang teramati, referensi sinyal, dan status peninjauan. Memerlukan read:networks. Intelijen global dan catatan analis privat tidak disertakan. Setiap daftar akun dan sinyal dibatasi maksimal 500 entri dan laporan menyatakan jika data tidak lengkap. Permintaan ini tidak mengubah status jaringan. Kesalahan dikembalikan sebagai JSON.",
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID organisasi."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID aplikasi."
          },
          {
            "name": "network_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID jaringan."
          },
          {
            "name": "Authorization",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Token akses pengguna konsol dalam format Bearer <token>."
          }
        ],
        "responses": {
          "200": {
            "description": "Laporan bukti jaringan. Cache-Control: no-store.",
            "content": {
              "application/pdf": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "401": {
            "description": "Autentikasi diperlukan."
          },
          "403": {
            "description": "Izin atau akses Networks tidak ada."
          },
          "404": {
            "description": "Jaringan atau catatan tidak terlihat oleh aplikasi ini."
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\n# Also needs a console user's access token.\nclient = Didit()\n\ncontent = client.networks.download_report(\n    \"11111111-2222-3333-4444-555555555555\",\n    extra_headers={\"Authorization\": \"Bearer YOUR_CONSOLE_USER_TOKEN\"},\n)\nwith open(\"download.pdf\", \"wb\") as file:\n    file.write(content)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import { writeFile } from \"node:fs/promises\";\nimport Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n// Also needs a console user's access token.\nconst didit = new Didit({\n  fetch: (url, init) => {\n    const headers = new Headers(init?.headers);\n    headers.set(\"Authorization\", \"Bearer YOUR_CONSOLE_USER_TOKEN\");\n    return fetch(url, { ...init, headers });\n  },\n});\n\nconst content = await didit.networks.downloadReport(\"11111111-2222-3333-4444-555555555555\");\nawait writeFile(\"download.pdf\", Buffer.from(await content.arrayBuffer()));"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n// Also needs a console user's access token.\nclient := didit.NewClient()\n\nresp, err := client.Networks.DownloadReport(ctx, \"11111111-2222-3333-4444-555555555555\", didit.NetworksDownloadReportParams{\n\tAuthorization: \"Bearer YOUR_CONSOLE_USER_TOKEN\",\n})\nif err != nil {\n\tlog.Fatal(err)\n}\ndefer resp.Body.Close()\nfile, err := os.Create(\"download.pdf\")\nif err != nil {\n\tlog.Fatal(err)\n}\ndefer file.Close()\nif _, err := io.Copy(file, resp.Body); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.nio.file.Path;\nimport me.didit.Didit;\nimport me.didit.core.RequestOptions;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n// Also needs a console user's access token.\nDidit client = new Didit();\n\nclient.networks().downloadReport(\"11111111-2222-3333-4444-555555555555\", RequestOptions.builder()\n        .header(\"Authorization\", \"Bearer YOUR_CONSOLE_USER_TOKEN\")\n        .build())\n        .writeTo(Path.of(\"download.pdf\"));"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n// Also needs a console user's access token.\n$didit = new DiditClient();\n\n$content = $didit->networks->downloadReport('11111111-2222-3333-4444-555555555555', [\n    'authorization' => 'Bearer YOUR_CONSOLE_USER_TOKEN',\n]);\n$content->saveTo('download.pdf');"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\n# Also needs a console user's access token.\ndidit = Didit::Client.new\n\ncontent = didit.networks.download_report(\n  \"11111111-2222-3333-4444-555555555555\",\n  request_options: { extra_headers: { \"Authorization\" => \"Bearer YOUR_CONSOLE_USER_TOKEN\" } }\n)\nFile.binwrite(\"download.pdf\", content)"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Collections.Generic;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n// Also needs a console user's access token.\nusing var client = new DiditClient();\n\nvar content = await client.Networks.DownloadReportAsync(\"11111111-2222-3333-4444-555555555555\", requestOptions: new RequestOptions\n{\n    Headers = new Dictionary<string, string>\n    {\n        [\"Authorization\"] = \"Bearer YOUR_CONSOLE_USER_TOKEN\",\n    },\n});\nawait content.SaveToAsync(\"download.pdf\");"
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/networks/{network_uuid}/notes/": {
      "get": {
        "operationId": "list_network_notes",
        "x-didit-sdk": {
          "resource": "networks.notes",
          "method": "list",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Networks"
        ],
        "summary": "Mencantumkan catatan jaringan privat",
        "description": "Pengguna konsol dengan read:networks dapat membaca catatan pada jaringan yang terlihat oleh aplikasi. Catatan tetap berada di dalam organisasi dan tidak dikontribusikan ke intelijen bersama. Catatan terbaru muncul lebih dahulu.",
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID organisasi."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID aplikasi."
          },
          {
            "name": "network_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID jaringan."
          },
          {
            "name": "Authorization",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Token akses pengguna konsol dalam format Bearer <token>."
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 30
            }
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "maximum": 1000000,
              "default": 0
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Satu halaman catatan. Jumlah dibatasi hingga 100; gunakan next untuk melanjutkan.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "count": {
                      "type": "integer"
                    },
                    "next": {
                      "type": "string",
                      "nullable": true
                    },
                    "previous": {
                      "type": "string",
                      "nullable": true
                    },
                    "results": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NetworkNote"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Autentikasi diperlukan."
          },
          "403": {
            "description": "Izin atau akses Networks tidak ada."
          },
          "404": {
            "description": "Jaringan atau catatan tidak terlihat oleh aplikasi ini."
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\n# Also needs a console user's access token.\nclient = Didit()\n\nfor item in client.networks.notes.list(\n    \"11111111-2222-3333-4444-555555555555\",\n    extra_headers={\"Authorization\": \"Bearer YOUR_CONSOLE_USER_TOKEN\"},\n):\n    print(item)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n// Also needs a console user's access token.\nconst didit = new Didit({\n  fetch: (url, init) => {\n    const headers = new Headers(init?.headers);\n    headers.set(\"Authorization\", \"Bearer YOUR_CONSOLE_USER_TOKEN\");\n    return fetch(url, { ...init, headers });\n  },\n});\n\nfor await (const item of didit.networks.notes.list(\"11111111-2222-3333-4444-555555555555\")) {\n  console.log(item);\n}"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n// Also needs a console user's access token.\nclient := didit.NewClient()\n\niter := client.Networks.Notes.ListAutoPaging(ctx, \"11111111-2222-3333-4444-555555555555\", didit.NetworksNotesListParams{\n\tAuthorization: \"Bearer YOUR_CONSOLE_USER_TOKEN\",\n})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.core.RequestOptions;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n// Also needs a console user's access token.\nDidit client = new Didit();\n\nfor (var item : client.networks().notes().list(\"11111111-2222-3333-4444-555555555555\", RequestOptions.builder()\n        .header(\"Authorization\", \"Bearer YOUR_CONSOLE_USER_TOKEN\")\n        .build())) {\n    System.out.println(item);\n}"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n// Also needs a console user's access token.\n$didit = new DiditClient();\n\nforeach ($didit->networks->notes->list('11111111-2222-3333-4444-555555555555', [\n    'authorization' => 'Bearer YOUR_CONSOLE_USER_TOKEN',\n]) as $item) {\n    print_r($item->toArray());\n}"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\n# Also needs a console user's access token.\ndidit = Didit::Client.new\n\ndidit.networks.notes.list(\n  \"11111111-2222-3333-4444-555555555555\",\n  request_options: { extra_headers: { \"Authorization\" => \"Bearer YOUR_CONSOLE_USER_TOKEN\" } }\n).auto_paging_each do |item|\n  puts item.to_h\nend"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n// Also needs a console user's access token.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.Networks.Notes.ListAsync(\"11111111-2222-3333-4444-555555555555\", requestOptions: new RequestOptions\n{\n    Headers = new Dictionary<string, string>\n    {\n        [\"Authorization\"] = \"Bearer YOUR_CONSOLE_USER_TOKEN\",\n    },\n}))\n{\n    Console.WriteLine(JsonSerializer.Serialize(item));\n}"
          }
        ]
      },
      "post": {
        "operationId": "create_network_note",
        "x-didit-sdk": {
          "resource": "networks.notes",
          "method": "create",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Networks"
        ],
        "summary": "Tambahkan catatan jaringan privat",
        "description": "Memerlukan pengguna konsol dengan write:networks. Penulis ditetapkan dari pengguna yang diautentikasi. Berikan UUID acak baru untuk client_reference pada setiap catatan; coba lagi body dan referensi yang sama setelah respons yang tidak pasti untuk menghindari duplikat. Menggunakan kembali referensi untuk body, penulis, atau jaringan lain akan mengembalikan 409. Catatan mengikuti investigasi yang bertahan ketika jaringan digabungkan.",
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID organisasi."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID aplikasi."
          },
          {
            "name": "network_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID jaringan."
          },
          {
            "name": "Authorization",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Token akses pengguna konsol dalam format Bearer <token>."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "comment",
                  "client_reference"
                ],
                "properties": {
                  "comment": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 10000
                  },
                  "client_reference": {
                    "type": "string",
                    "format": "uuid"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Catatan pribadi tersimpan.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NetworkNote"
                }
              }
            }
          },
          "200": {
            "description": "Catatan pribadi tersimpan.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NetworkNote"
                }
              }
            }
          },
          "400": {
            "description": "Catatan tidak valid atau kosong."
          },
          "409": {
            "description": "Referensi telah digunakan untuk catatan lain."
          },
          "401": {
            "description": "Autentikasi diperlukan."
          },
          "403": {
            "description": "Izin atau akses Networks tidak ada."
          },
          "404": {
            "description": "Jaringan atau catatan tidak terlihat oleh aplikasi ini."
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\n# Also needs a console user's access token.\nclient = Didit()\n\nresult = client.networks.notes.create(\n    \"11111111-2222-3333-4444-555555555555\",\n    comment=\"your-comment\",\n    client_reference=\"11111111-2222-3333-4444-555555555555\",\n    extra_headers={\"Authorization\": \"Bearer YOUR_CONSOLE_USER_TOKEN\"},\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n// Also needs a console user's access token.\nconst didit = new Didit({\n  fetch: (url, init) => {\n    const headers = new Headers(init?.headers);\n    headers.set(\"Authorization\", \"Bearer YOUR_CONSOLE_USER_TOKEN\");\n    return fetch(url, { ...init, headers });\n  },\n});\n\nconst result = await didit.networks.notes.create(\"11111111-2222-3333-4444-555555555555\", {\n  comment: \"your-comment\",\n  client_reference: \"11111111-2222-3333-4444-555555555555\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n// Also needs a console user's access token.\nclient := didit.NewClient()\n\nresult, err := client.Networks.Notes.Create(ctx, \"11111111-2222-3333-4444-555555555555\", didit.NetworksNotesCreateParams{\n\tComment:         \"your-comment\",\n\tClientReference: \"11111111-2222-3333-4444-555555555555\",\n\tAuthorization:   \"Bearer YOUR_CONSOLE_USER_TOKEN\",\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.core.RequestOptions;\nimport me.didit.types.NetworksNotesCreateParams;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n// Also needs a console user's access token.\nDidit client = new Didit();\n\nvar result = client.networks().notes().create(\"11111111-2222-3333-4444-555555555555\", NetworksNotesCreateParams.builder()\n        .comment(\"your-comment\")\n        .clientReference(\"11111111-2222-3333-4444-555555555555\")\n        .build(), RequestOptions.builder()\n        .header(\"Authorization\", \"Bearer YOUR_CONSOLE_USER_TOKEN\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n// Also needs a console user's access token.\n$didit = new DiditClient();\n\n$result = $didit->networks->notes->create('11111111-2222-3333-4444-555555555555', [\n    'comment' => 'your-comment',\n    'client_reference' => '11111111-2222-3333-4444-555555555555',\n    'authorization' => 'Bearer YOUR_CONSOLE_USER_TOKEN',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\n# Also needs a console user's access token.\ndidit = Didit::Client.new\n\nresult = didit.networks.notes.create(\n  \"11111111-2222-3333-4444-555555555555\",\n  comment: \"your-comment\",\n  client_reference: \"11111111-2222-3333-4444-555555555555\",\n  request_options: { extra_headers: { \"Authorization\" => \"Bearer YOUR_CONSOLE_USER_TOKEN\" } }\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n// Also needs a console user's access token.\nusing var client = new DiditClient();\n\nvar result = await client.Networks.Notes.CreateAsync(\"11111111-2222-3333-4444-555555555555\", new NetworksNotesCreateParams\n{\n    Comment = \"your-comment\",\n    ClientReference = \"11111111-2222-3333-4444-555555555555\",\n}, requestOptions: new RequestOptions\n{\n    Headers = new Dictionary<string, string>\n    {\n        [\"Authorization\"] = \"Bearer YOUR_CONSOLE_USER_TOKEN\",\n    },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/cases/routing-rules/{record_uuid}/draft/": {
      "get": {
        "operationId": "get_case_routing_rule_draft",
        "x-didit-sdk": {
          "resource": "cases.routing_rules",
          "method": "retrieve_draft",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "parameters": [
          {
            "in": "path",
            "name": "organization_id",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          },
          {
            "in": "path",
            "name": "application_id",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          },
          {
            "in": "path",
            "name": "record_uuid",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          }
        ],
        "tags": [
          "Case Assignment"
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RoutingPublicationPolicyDraftResponse"
                }
              }
            },
            "description": ""
          },
          "403": {
            "description": "Akses kasus diperlukan."
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.routing_rules.retrieve_draft(\n    \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.routingRules.retrieveDraft(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.RoutingRules.RetrieveDraft(ctx, \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().routingRules().retrieveDraft(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->cases->routingRules->retrieveDraft('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.routing_rules.retrieve_draft(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.RoutingRules.RetrieveDraftAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      },
      "put": {
        "operationId": "save_case_routing_rule_draft",
        "x-didit-sdk": {
          "resource": "cases.routing_rules",
          "method": "save_draft",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "parameters": [
          {
            "in": "path",
            "name": "organization_id",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          },
          {
            "in": "path",
            "name": "application_id",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          },
          {
            "in": "path",
            "name": "record_uuid",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          }
        ],
        "tags": [
          "Case Assignment"
        ],
        "requestBody": {
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/RoutingPublicationPolicyDraftWriteRequest"
              }
            },
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RoutingPublicationPolicyDraftWriteRequest"
              },
              "example": {
                "expected_version": 1,
                "expected_revision": "4e5f0000-0000-4000-8000-000000000003",
                "changes": {
                  "priority": 10
                }
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/RoutingPublicationPolicyDraftWriteRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RoutingPublicationPolicyDraft"
                }
              }
            },
            "description": ""
          },
          "403": {
            "description": "Akses kasus diperlukan."
          },
          "409": {
            "description": "Versi yang dipublikasikan atau revisi draf telah berubah. Muat ulang sebelum mencoba lagi."
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.routing_rules.save_draft(\n    \"11111111-2222-3333-4444-555555555555\",\n    expected_version=1,\n    expected_revision=\"4e5f0000-0000-4000-8000-000000000003\",\n    changes={\"priority\": 10},\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.routingRules.saveDraft(\"11111111-2222-3333-4444-555555555555\", {\n  expected_version: 1,\n  expected_revision: \"4e5f0000-0000-4000-8000-000000000003\",\n  changes: { priority: 10 },\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.RoutingRules.SaveDraft(ctx, \"11111111-2222-3333-4444-555555555555\", didit.RoutingPublicationPolicyDraftWriteRequest{\n\tExpectedVersion:  1,\n\tExpectedRevision: didit.String(\"4e5f0000-0000-4000-8000-000000000003\"),\n\tChanges:          map[string]any{\"priority\": 10},\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.RoutingPublicationPolicyDraftWriteRequest;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().routingRules().saveDraft(\"11111111-2222-3333-4444-555555555555\", RoutingPublicationPolicyDraftWriteRequest.builder()\n        .expectedVersion(1L)\n        .expectedRevision(\"4e5f0000-0000-4000-8000-000000000003\")\n        .changes(Map.of(\"priority\", 10))\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->cases->routingRules->saveDraft('11111111-2222-3333-4444-555555555555', [\n    'expected_version' => 1,\n    'expected_revision' => '4e5f0000-0000-4000-8000-000000000003',\n    'changes' => ['priority' => 10],\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.routing_rules.save_draft(\n  \"11111111-2222-3333-4444-555555555555\",\n  expected_version: 1,\n  expected_revision: \"4e5f0000-0000-4000-8000-000000000003\",\n  changes: { priority: 10 }\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.RoutingRules.SaveDraftAsync(\"11111111-2222-3333-4444-555555555555\", new RoutingPublicationPolicyDraftWriteRequest\n{\n    ExpectedVersion = 1,\n    ExpectedRevision = \"4e5f0000-0000-4000-8000-000000000003\",\n    Changes = new Dictionary<string, object> { [\"priority\"] = 10 },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      },
      "delete": {
        "operationId": "discard_case_routing_rule_draft",
        "x-didit-sdk": {
          "resource": "cases.routing_rules",
          "method": "discard_draft",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "parameters": [
          {
            "in": "path",
            "name": "organization_id",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          },
          {
            "in": "path",
            "name": "application_id",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          },
          {
            "in": "path",
            "name": "record_uuid",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          }
        ],
        "tags": [
          "Case Assignment"
        ],
        "responses": {
          "204": {
            "description": "Tidak ada body respons"
          },
          "403": {
            "description": "Akses kasus diperlukan."
          },
          "409": {
            "description": "Versi yang dipublikasikan atau revisi draf telah berubah. Muat ulang sebelum mencoba lagi."
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RoutingPublicationPolicyDraftPreconditionRequest"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nclient.cases.routing_rules.discard_draft(\n    \"11111111-2222-3333-4444-555555555555\",\n    expected_version=0,\n    expected_revision=\"11111111-2222-3333-4444-555555555555\",\n)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nawait didit.cases.routingRules.discardDraft(\"11111111-2222-3333-4444-555555555555\", {\n  expected_version: 0,\n  expected_revision: \"11111111-2222-3333-4444-555555555555\",\n});"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nif err := client.Cases.RoutingRules.DiscardDraft(ctx, \"11111111-2222-3333-4444-555555555555\", didit.RoutingPublicationPolicyDraftPreconditionRequest{\n\tExpectedVersion:  0,\n\tExpectedRevision: didit.String(\"11111111-2222-3333-4444-555555555555\"),\n}); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.RoutingPublicationPolicyDraftPreconditionRequest;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nclient.cases().routingRules().discardDraft(\"11111111-2222-3333-4444-555555555555\", RoutingPublicationPolicyDraftPreconditionRequest.builder()\n        .expectedVersion(0L)\n        .expectedRevision(\"11111111-2222-3333-4444-555555555555\")\n        .build());"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$didit->cases->routingRules->discardDraft('11111111-2222-3333-4444-555555555555', [\n    'expected_version' => 0,\n    'expected_revision' => '11111111-2222-3333-4444-555555555555',\n]);"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\ndidit.cases.routing_rules.discard_draft(\n  \"11111111-2222-3333-4444-555555555555\",\n  expected_version: 0,\n  expected_revision: \"11111111-2222-3333-4444-555555555555\"\n)"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nawait client.Cases.RoutingRules.DiscardDraftAsync(\"11111111-2222-3333-4444-555555555555\", new RoutingPublicationPolicyDraftPreconditionRequest\n{\n    ExpectedVersion = 0,\n    ExpectedRevision = \"11111111-2222-3333-4444-555555555555\",\n});"
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/cases/duplicates/": {
      "post": {
        "operationId": "duplicates_create",
        "x-didit-sdk": {
          "resource": "cases",
          "method": "find_duplicates",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "parameters": [
          {
            "in": "path",
            "name": "organization_id",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          },
          {
            "in": "path",
            "name": "application_id",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          }
        ],
        "tags": [
          "Case Management"
        ],
        "requestBody": {
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/CaseDuplicateCaseDuplicateQueryRequest"
              }
            },
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CaseDuplicateCaseDuplicateQueryRequest"
              },
              "example": {
                "subject": {
                  "type": "user",
                  "uuid": "5b9a0000-0000-4000-8000-00000000f00d"
                }
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/CaseDuplicateCaseDuplicateQueryRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CaseDuplicateCaseDuplicatePage"
                }
              }
            },
            "description": ""
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "description": "Tinjau kasus yang ada untuk suatu subjek atau catatan sumber yang dimiliki sebelum pembuatan kasus manual. Investigasi yang terbuka maupun yang sudah diselesaikan akan dikembalikan. Setiap halaman berisi paling banyak 20 kasus; gunakan next_offset untuk meminta halaman lain.",
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.find_duplicates(\n    subject={\n        \"type\": \"user\",\n        \"uuid\": \"5b9a0000-0000-4000-8000-00000000f00d\",\n    },\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.findDuplicates({\n  subject: {\n    type: \"user\",\n    uuid: \"5b9a0000-0000-4000-8000-00000000f00d\",\n  },\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.FindDuplicates(ctx, didit.CaseDuplicateCaseDuplicateQueryRequest{\n\tSubject: didit.Some(didit.CaseDuplicateCaseSubjectInputRequest{\n\t\tType: didit.CaseDuplicateTypeEnum(\"user\"),\n\t\tUUID: \"5b9a0000-0000-4000-8000-00000000f00d\",\n\t}),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.CaseDuplicateCaseDuplicateQueryRequest;\nimport me.didit.types.CaseDuplicateCaseSubjectInputRequest;\nimport me.didit.types.CaseDuplicateTypeEnum;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().findDuplicates(CaseDuplicateCaseDuplicateQueryRequest.builder()\n        .subject(CaseDuplicateCaseSubjectInputRequest.builder()\n                .type(CaseDuplicateTypeEnum.of(\"user\"))\n                .uuid(\"5b9a0000-0000-4000-8000-00000000f00d\")\n                .build())\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->cases->findDuplicates([\n    'subject' => [\n        'type' => 'user',\n        'uuid' => '5b9a0000-0000-4000-8000-00000000f00d',\n    ],\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.find_duplicates(\n  subject: {\n    type: \"user\",\n    uuid: \"5b9a0000-0000-4000-8000-00000000f00d\",\n  }\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.FindDuplicatesAsync(new CaseDuplicateCaseDuplicateQueryRequest\n{\n    Subject = new CaseDuplicateCaseSubjectInputRequest\n    {\n        Type = \"user\",\n        Uuid = \"5b9a0000-0000-4000-8000-00000000f00d\",\n    },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/cases/routing-rules/preview/": {
      "post": {
        "summary": "Uji perutean kasus",
        "description": "Memerlukan `read:cases` untuk aplikasi yang diminta. Mengevaluasi aturan saat ini atau draf yang diberikan terhadap akses, ketersediaan, keahlian, dan kapasitas peninjau saat ini. Ini tidak menyimpan draf atau mencadangkan kapasitas peninjau.",
        "operationId": "preview_case_routing",
        "x-didit-sdk": {
          "resource": "cases.routing_rules",
          "method": "preview",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Case Assignment"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID organisasi."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID aplikasi."
          }
        ],
        "responses": {
          "200": {
            "description": "Berhasil",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CaseRoutingPreview"
                }
              }
            }
          },
          "400": {
            "description": "Input tidak valid."
          },
          "403": {
            "description": "Izin tidak memadai."
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CaseRoutingPreviewRequest"
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.routing_rules.preview(\n    source=\"MANUAL\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.routingRules.preview({\n  source: \"MANUAL\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.RoutingRules.Preview(ctx, didit.CaseRoutingPreviewRequest{\n\tSource: \"MANUAL\",\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.CaseRoutingPreviewRequest;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().routingRules().preview(CaseRoutingPreviewRequest.builder()\n        .source(CaseRoutingPreviewRequest.Source.of(\"MANUAL\"))\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->cases->routingRules->preview([\n    'source' => 'MANUAL',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.routing_rules.preview(source: \"MANUAL\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.RoutingRules.PreviewAsync(new CaseRoutingPreviewRequest\n{\n    Source = \"MANUAL\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/cases/reviewers/": {
      "get": {
        "summary": "Daftar peninjau kasus yang memenuhi syarat",
        "description": "Memerlukan `list:cases` untuk aplikasi yang diminta.",
        "operationId": "list_case_reviewers",
        "x-didit-sdk": {
          "resource": "cases",
          "method": "list_reviewers",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Case Assignment"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID organisasi."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID aplikasi."
          }
        ],
        "responses": {
          "200": {
            "description": "Berhasil",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "results": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "user_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "email": {
                            "type": "string",
                            "format": "email"
                          },
                          "name": {
                            "type": "string"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Input tidak valid."
          },
          "403": {
            "description": "Izin tidak memadai."
          },
          "503": {
            "description": "Akses peninjau tidak dapat diverifikasi. Coba lagi nanti."
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.list_reviewers()\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.listReviewers();\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.ListReviewers(ctx)\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().listReviewers();\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->cases->listReviewers();\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.list_reviewers\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.ListReviewersAsync();\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/cases/blueprints/{blueprint_uuid}/history/": {
      "get": {
        "operationId": "list_case_blueprint_history",
        "x-didit-sdk": {
          "resource": "cases.blueprints",
          "method": "list_history",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "parameters": [
          {
            "in": "path",
            "name": "organization_id",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          },
          {
            "in": "path",
            "name": "application_id",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          },
          {
            "in": "path",
            "name": "blueprint_uuid",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true
          },
          {
            "name": "ordering",
            "required": false,
            "in": "query",
            "description": "Kolom mana yang digunakan saat mengurutkan hasil.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "description": "Jumlah hasil yang dikembalikan per halaman.",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "offset",
            "required": false,
            "in": "query",
            "description": "Indeks awal yang digunakan untuk mengembalikan hasil.",
            "schema": {
              "type": "integer"
            }
          }
        ],
        "tags": [
          "Case Management"
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CasePublicationPaginatedPolicyRevisionList"
                }
              }
            },
            "description": ""
          },
          "403": {
            "description": "Izin kasus yang diperlukan tidak ada."
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nfor item in client.cases.blueprints.list_history(\n    \"11111111-2222-3333-4444-555555555555\",\n):\n    print(item)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nfor await (const item of didit.cases.blueprints.listHistory(\"11111111-2222-3333-4444-555555555555\")) {\n  console.log(item);\n}"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\niter := client.Cases.Blueprints.ListHistoryAutoPaging(ctx, \"11111111-2222-3333-4444-555555555555\", didit.CasesBlueprintsListHistoryParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nfor (var item : client.cases().blueprints().listHistory(\"11111111-2222-3333-4444-555555555555\")) {\n    System.out.println(item);\n}"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\nforeach ($didit->cases->blueprints->listHistory('11111111-2222-3333-4444-555555555555') as $item) {\n    print_r($item->toArray());\n}"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\ndidit.cases.blueprints.list_history(\"11111111-2222-3333-4444-555555555555\").auto_paging_each do |item|\n  puts item.to_h\nend"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.Cases.Blueprints.ListHistoryAsync(\"11111111-2222-3333-4444-555555555555\"))\n{\n    Console.WriteLine(JsonSerializer.Serialize(item));\n}"
          }
        ]
      }
    },
    "/v3/session/{sessionId}/signatures/{nodeId}/documents/{documentId}/file/": {
      "get": {
        "summary": "Unduh dokumen yang ditandatangani",
        "description": "Unduh PDF yang ditandatangani dari satu dokumen pada langkah Tanda Tangan Elektronik. Gunakan jalur `signed_file` dari `signatures[].documents[]` dalam keputusan. PDF memuat dokumen yang diperlihatkan kepada penandatangan dengan nilai kolom yang telah dibubuhkan dan halaman bukti (kecuali jika `signature_evidence_page` dimatikan). PDF Lanjutan (AES) juga memuat tanda tangan PAdES beserta stempel waktunya; PDF Sederhana tidak memiliki tanda tangan digital, segel, atau stempel waktu. Didit memeriksa file terhadap `sha256_signed` sebelum mengembalikannya.\n\nBerfungsi untuk sesi Verifikasi Pengguna (KYC) dan Verifikasi Bisnis (KYB). Memerlukan `read:sessions`; kunci API Anda berfungsi. Lihat [Laporan Tanda Tangan Elektronik](/id/core-technology/electronic-signature/report-electronic-signature#unduh-dokumen-yang-ditandatangani).",
        "operationId": "get_v3_session_signature_document_file",
        "x-didit-sdk": {
          "resource": "sessions.signatures",
          "method": "download_document",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Sessions"
        ],
        "parameters": [
          {
            "name": "sessionId",
            "in": "path",
            "required": true,
            "description": "Sesi Verifikasi Pengguna (KYC) atau Verifikasi Bisnis (KYB).",
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "11111111-2222-3333-4444-555555555555"
            }
          },
          {
            "name": "nodeId",
            "in": "path",
            "required": true,
            "description": "Langkah Tanda Tangan Elektronik: `node_id` dari item dalam `signatures[]`.",
            "schema": {
              "type": "string",
              "example": "feature_signature"
            }
          },
          {
            "name": "documentId",
            "in": "path",
            "required": true,
            "description": "`id` dokumen di `signatures[].documents[]`.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "PDF yang telah ditandatangani.",
            "headers": {
              "Content-Disposition": {
                "description": "Lampiran dengan nama file.",
                "schema": {
                  "type": "string",
                  "example": "attachment; filename=\"agreement-signed.pdf\""
                }
              }
            },
            "content": {
              "application/pdf": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "403": {
            "description": "Kredensial tidak ada, atau kredensial yang tidak dapat membaca sesi ini. Kunci yang tidak ada mengembalikan `403`; kunci yang salah, dicabut, atau kedaluwarsa mengembalikan `401`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "detail": "You do not have permission to perform this action."
                }
              }
            }
          },
          "404": {
            "description": "Tidak ada dokumen bertanda tangan yang cocok: sesi, langkah, atau dokumen tidak ada, telah dihapus, atau belum ditandatangani.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string"
                    },
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Not signed yet": {
                    "summary": "Penandatangan belum menandatangani",
                    "value": {
                      "code": "signature_not_signed",
                      "detail": "signature_not_signed"
                    }
                  },
                  "Unknown document": {
                    "summary": "Tidak ada dokumen seperti itu di langkah ini",
                    "value": {
                      "code": "signature_not_found",
                      "detail": "signature_not_found"
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "File yang disimpan tidak lagi cocok dengan SHA-256 yang tercatat. Tidak ada yang dikembalikan.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string"
                    },
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Changed file": {
                    "summary": "File tersimpan tidak cocok dengan hash miliknya",
                    "value": {
                      "code": "signature_document_changed",
                      "detail": "signature_document_changed"
                    }
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\ncontent = client.sessions.signatures.download_document(\n    \"11111111-2222-3333-4444-555555555555\",\n    \"feature_signature\",\n    \"11111111-2222-3333-4444-555555555555\",\n)\nwith open(\"download.pdf\", \"wb\") as file:\n    file.write(content)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import { writeFile } from \"node:fs/promises\";\nimport Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst content = await didit.sessions.signatures.downloadDocument(\n  \"11111111-2222-3333-4444-555555555555\",\n  \"feature_signature\",\n  \"11111111-2222-3333-4444-555555555555\",\n);\nawait writeFile(\"download.pdf\", Buffer.from(await content.arrayBuffer()));"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresp, err := client.Sessions.Signatures.DownloadDocument(ctx, \"11111111-2222-3333-4444-555555555555\", \"feature_signature\", \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\ndefer resp.Body.Close()\nfile, err := os.Create(\"download.pdf\")\nif err != nil {\n\tlog.Fatal(err)\n}\ndefer file.Close()\nif _, err := io.Copy(file, resp.Body); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.nio.file.Path;\nimport me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nclient.sessions().signatures().downloadDocument(\"11111111-2222-3333-4444-555555555555\", \"feature_signature\", \"11111111-2222-3333-4444-555555555555\")\n        .writeTo(Path.of(\"download.pdf\"));"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$content = $didit->sessions->signatures->downloadDocument('11111111-2222-3333-4444-555555555555', 'feature_signature', '11111111-2222-3333-4444-555555555555');\n$content->saveTo('download.pdf');"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ncontent = didit.sessions.signatures.download_document(\n  \"11111111-2222-3333-4444-555555555555\",\n  \"feature_signature\",\n  \"11111111-2222-3333-4444-555555555555\"\n)\nFile.binwrite(\"download.pdf\", content)"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar content = await client.Sessions.Signatures.DownloadDocumentAsync(\"11111111-2222-3333-4444-555555555555\", \"feature_signature\", \"11111111-2222-3333-4444-555555555555\");\nawait content.SaveToAsync(\"download.pdf\");"
          }
        ]
      }
    },
    "/v3/session/{sessionId}/signatures/{nodeId}/evidence/": {
      "get": {
        "summary": "Unduh bukti tanda tangan",
        "description": "Unduh PDF bukti penandatangan: tingkat dan format, penandatangan, alamat IP, setiap dokumen beserta SHA-256 asli dan nilai kolomnya serta SHA-256 dari setiap file yang ditandatangani, ditambah lagi, untuk tanda tangan Lanjutan (AES), sesi verifikasi identitas, konfirmasi kode, sertifikat, dan stempel waktu. Gunakan jalur `evidence_file` dari item penandatangan di `signatures[]`.\n\nSelalu berikan `signature_id` saat langkah Verifikasi Bisnis memiliki beberapa penandatangan: tanpanya, rute akan memilih salah satu penandatangan langkah tersebut. Memerlukan `read:sessions`; kunci API Anda berfungsi.",
        "operationId": "get_v3_session_signature_evidence",
        "x-didit-sdk": {
          "resource": "sessions.signatures",
          "method": "download_evidence",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Sessions"
        ],
        "parameters": [
          {
            "name": "sessionId",
            "in": "path",
            "required": true,
            "description": "Sesi Verifikasi Pengguna (KYC) atau Verifikasi Bisnis (KYB).",
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "11111111-2222-3333-4444-555555555555"
            }
          },
          {
            "name": "nodeId",
            "in": "path",
            "required": true,
            "description": "Langkah Tanda Tangan Elektronik: `node_id` dari item dalam `signatures[]`.",
            "schema": {
              "type": "string",
              "example": "feature_signature"
            }
          },
          {
            "name": "signature_id",
            "in": "query",
            "required": false,
            "description": "`id` dari item penandatangan di `signatures[]`.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "PDF bukti.",
            "headers": {
              "Content-Disposition": {
                "description": "Lampiran dengan nama file.",
                "schema": {
                  "type": "string",
                  "example": "attachment; filename=\"signature-evidence.pdf\""
                }
              }
            },
            "content": {
              "application/pdf": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "403": {
            "description": "Kredensial tidak ada, atau kredensial yang tidak dapat membaca sesi ini. Kunci yang tidak ada mengembalikan `403`; kunci yang salah, dicabut, atau kedaluwarsa mengembalikan `401`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "detail": "You do not have permission to perform this action."
                }
              }
            }
          },
          "404": {
            "description": "Tidak ada bukti yang cocok: sesi, langkah, atau penandatangan tidak ada, telah dihapus, atau belum menandatangani.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string"
                    },
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Not signed yet": {
                    "summary": "Penandatangan belum menandatangani",
                    "value": {
                      "code": "signature_not_signed",
                      "detail": "signature_not_signed"
                    }
                  },
                  "Unknown signer": {
                    "summary": "Tidak ada tanda tangan seperti itu di langkah ini",
                    "value": {
                      "code": "signature_not_found",
                      "detail": "signature_not_found"
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "File yang disimpan tidak lagi cocok dengan SHA-256 yang tercatat. Tidak ada yang dikembalikan.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string"
                    },
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Changed file": {
                    "summary": "File tersimpan tidak cocok dengan hash miliknya",
                    "value": {
                      "code": "signature_document_changed",
                      "detail": "signature_document_changed"
                    }
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\ncontent = client.sessions.signatures.download_evidence(\n    \"11111111-2222-3333-4444-555555555555\",\n    \"feature_signature\",\n)\nwith open(\"download.pdf\", \"wb\") as file:\n    file.write(content)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import { writeFile } from \"node:fs/promises\";\nimport Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst content = await didit.sessions.signatures.downloadEvidence(\n  \"11111111-2222-3333-4444-555555555555\",\n  \"feature_signature\",\n);\nawait writeFile(\"download.pdf\", Buffer.from(await content.arrayBuffer()));"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresp, err := client.Sessions.Signatures.DownloadEvidence(ctx, \"11111111-2222-3333-4444-555555555555\", \"feature_signature\", didit.SessionsSignaturesDownloadEvidenceParams{})\nif err != nil {\n\tlog.Fatal(err)\n}\ndefer resp.Body.Close()\nfile, err := os.Create(\"download.pdf\")\nif err != nil {\n\tlog.Fatal(err)\n}\ndefer file.Close()\nif _, err := io.Copy(file, resp.Body); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.nio.file.Path;\nimport me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nclient.sessions().signatures().downloadEvidence(\"11111111-2222-3333-4444-555555555555\", \"feature_signature\")\n        .writeTo(Path.of(\"download.pdf\"));"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$content = $didit->sessions->signatures->downloadEvidence('11111111-2222-3333-4444-555555555555', 'feature_signature');\n$content->saveTo('download.pdf');"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ncontent = didit.sessions.signatures.download_evidence(\n  \"11111111-2222-3333-4444-555555555555\",\n  \"feature_signature\"\n)\nFile.binwrite(\"download.pdf\", content)"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar content = await client.Sessions.Signatures.DownloadEvidenceAsync(\"11111111-2222-3333-4444-555555555555\", \"feature_signature\");\nawait content.SaveToAsync(\"download.pdf\");"
          }
        ]
      }
    },
    "/v3/session/{sessionId}/signatures/{nodeId}/fields/{fieldId}/image/": {
      "get": {
        "summary": "Unduh gambar tanda tangan",
        "description": "Unduh tanda tangan atau inisial yang dibubuhkan penandatangan pada suatu kolom, sebagai PNG. Gunakan `image_url` dari kolom di `signatures[].documents[].fields[]`. Memerlukan `read:sessions`; kunci API Anda berfungsi.",
        "operationId": "get_v3_session_signature_field_image",
        "x-didit-sdk": {
          "resource": "sessions.signatures",
          "method": "download_field_image",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Sessions"
        ],
        "parameters": [
          {
            "name": "sessionId",
            "in": "path",
            "required": true,
            "description": "Sesi Verifikasi Pengguna (KYC) atau Verifikasi Bisnis (KYB).",
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "11111111-2222-3333-4444-555555555555"
            }
          },
          {
            "name": "nodeId",
            "in": "path",
            "required": true,
            "description": "Langkah Tanda Tangan Elektronik: `node_id` dari item dalam `signatures[]`.",
            "schema": {
              "type": "string",
              "example": "feature_signature"
            }
          },
          {
            "name": "fieldId",
            "in": "path",
            "required": true,
            "description": "Kolom pada salinan penanda tangan ini, seperti `image_url` milik kolom tersebut.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Gambar.",
            "content": {
              "image/png": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "400": {
            "description": "Gambar yang disimpan tidak lagi cocok dengan SHA-256 yang tercatat.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string"
                    },
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "code": "signature_document_changed",
                  "detail": "signature_document_changed"
                }
              }
            }
          },
          "403": {
            "description": "Kredensial tidak ada, atau kredensial yang tidak dapat membaca sesi ini. Kunci yang tidak ada mengembalikan `403`; kunci yang salah, dicabut, atau kedaluwarsa mengembalikan `401`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "detail": "You do not have permission to perform this action."
                }
              }
            }
          },
          "404": {
            "description": "Tidak ada gambar yang cocok: sesi, langkah, atau kolom tidak ada, telah dihapus, atau tidak memiliki tanda tangan maupun inisial yang diterapkan.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string"
                    },
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Unknown field": {
                    "summary": "Tidak ada kolom seperti itu",
                    "value": {
                      "code": "signature_field_not_found",
                      "detail": "signature_field_not_found"
                    }
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\ncontent = client.sessions.signatures.download_field_image(\n    \"11111111-2222-3333-4444-555555555555\",\n    \"feature_signature\",\n    \"11111111-2222-3333-4444-555555555555\",\n)\nwith open(\"download.png\", \"wb\") as file:\n    file.write(content)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import { writeFile } from \"node:fs/promises\";\nimport Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst content = await didit.sessions.signatures.downloadFieldImage(\n  \"11111111-2222-3333-4444-555555555555\",\n  \"feature_signature\",\n  \"11111111-2222-3333-4444-555555555555\",\n);\nawait writeFile(\"download.png\", Buffer.from(await content.arrayBuffer()));"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresp, err := client.Sessions.Signatures.DownloadFieldImage(ctx, \"11111111-2222-3333-4444-555555555555\", \"feature_signature\", \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\ndefer resp.Body.Close()\nfile, err := os.Create(\"download.png\")\nif err != nil {\n\tlog.Fatal(err)\n}\ndefer file.Close()\nif _, err := io.Copy(file, resp.Body); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.nio.file.Path;\nimport me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nclient.sessions().signatures().downloadFieldImage(\"11111111-2222-3333-4444-555555555555\", \"feature_signature\", \"11111111-2222-3333-4444-555555555555\")\n        .writeTo(Path.of(\"download.png\"));"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$content = $didit->sessions->signatures->downloadFieldImage('11111111-2222-3333-4444-555555555555', 'feature_signature', '11111111-2222-3333-4444-555555555555');\n$content->saveTo('download.png');"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ncontent = didit.sessions.signatures.download_field_image(\n  \"11111111-2222-3333-4444-555555555555\",\n  \"feature_signature\",\n  \"11111111-2222-3333-4444-555555555555\"\n)\nFile.binwrite(\"download.png\", content)"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar content = await client.Sessions.Signatures.DownloadFieldImageAsync(\"11111111-2222-3333-4444-555555555555\", \"feature_signature\", \"11111111-2222-3333-4444-555555555555\");\nawait content.SaveToAsync(\"download.png\");"
          }
        ]
      }
    },
    "/v3/session/{sessionId}/signatures/{nodeId}/validate/": {
      "post": {
        "summary": "Validasi tanda tangan lagi",
        "description": "Periksa ulang dokumen yang telah ditandatangani dari langkah Tanda Tangan Elektronik. Didit membaca ulang setiap PDF yang ditandatangani, memeriksa SHA-256-nya, dan untuk tanda tangan Tingkat Lanjut (AES), memvalidasi tanda tangan PAdES, sertifikat, data pencabutan, dan stempel waktu (tanda tangan Sederhana tidak memiliki tanda tangan digital, sehingga hanya integritas file yang diperiksa), lalu menyimpan hasilnya di `validation` setiap penanda tangan dan mengembalikan item yang telah diperbarui. Tidak ada dokumen yang ditandatangani ulang. Kirim `signature_id` untuk memeriksa satu penanda tangan; tanpa parameter ini, setiap penanda tangan dalam langkah tersebut akan diperiksa, dan panggilan akan gagal jika ada yang belum menandatangani.\n\nMemerlukan `write:sessions`; kunci API Anda dapat digunakan. Di konsol, ini adalah tombol **Validate again**.",
        "operationId": "post_v3_session_signature_validate",
        "x-didit-sdk": {
          "resource": "sessions.signatures",
          "method": "validate",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Sessions"
        ],
        "parameters": [
          {
            "name": "sessionId",
            "in": "path",
            "required": true,
            "description": "Sesi Verifikasi Pengguna (KYC) atau Verifikasi Bisnis (KYB).",
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "11111111-2222-3333-4444-555555555555"
            }
          },
          {
            "name": "nodeId",
            "in": "path",
            "required": true,
            "description": "Langkah Tanda Tangan Elektronik: `node_id` dari item dalam `signatures[]`.",
            "schema": {
              "type": "string",
              "example": "feature_signature"
            }
          }
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "signature_id": {
                    "type": "string",
                    "format": "uuid",
                    "description": "`id` dari satu item penandatangan di `signatures[]`."
                  }
                }
              },
              "example": {
                "signature_id": "0e6c2a8e-6c2f-4b8e-9a51-3f2f6a7d9b10"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Penandatangan yang diperiksa, beserta `validation` terbarunya.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "signatures": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/SignatureResult"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "PDF bertanda tangan yang disimpan tidak lagi cocok dengan SHA-256 yang dicatat saat ditandatangani.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string"
                    },
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Document changed": {
                    "summary": "File yang ditandatangani tidak lagi cocok dengan hash-nya",
                    "value": {
                      "code": "signature_document_changed",
                      "detail": "signature_document_changed"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Kredensial tidak ada, atau kredensial yang tidak dapat membaca sesi ini. Kunci yang tidak ada mengembalikan `403`; kunci yang salah, dicabut, atau kedaluwarsa mengembalikan `401`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "detail": "You do not have permission to perform this action."
                }
              }
            }
          },
          "404": {
            "description": "Tidak ada tanda tangan yang cocok: sesi, langkah, atau penandatangan tidak ada atau telah dihapus.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string"
                    },
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Unknown signer": {
                    "summary": "Tidak ada tanda tangan seperti itu di langkah ini",
                    "value": {
                      "code": "signature_not_found",
                      "detail": "signature_not_found"
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "Penandatangan langkah ini belum menandatangani, sehingga tidak ada yang dapat divalidasi.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string"
                    },
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Not signed": {
                    "summary": "Penandatangan belum menandatangani",
                    "value": {
                      "code": "signature_not_signed",
                      "detail": "signature_not_signed"
                    }
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.signatures.validate(\n    \"11111111-2222-3333-4444-555555555555\",\n    \"feature_signature\",\n    signature_id=\"0e6c2a8e-6c2f-4b8e-9a51-3f2f6a7d9b10\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.signatures.validate(\n  \"11111111-2222-3333-4444-555555555555\",\n  \"feature_signature\",\n  {\n    signature_id: \"0e6c2a8e-6c2f-4b8e-9a51-3f2f6a7d9b10\",\n  },\n);\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.Signatures.Validate(ctx, \"11111111-2222-3333-4444-555555555555\", \"feature_signature\", didit.SessionsSignaturesValidateParams{\n\tSignatureID: didit.String(\"0e6c2a8e-6c2f-4b8e-9a51-3f2f6a7d9b10\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.SessionsSignaturesValidateParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().signatures().validate(\"11111111-2222-3333-4444-555555555555\", \"feature_signature\", SessionsSignaturesValidateParams.builder()\n        .signatureId(\"0e6c2a8e-6c2f-4b8e-9a51-3f2f6a7d9b10\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->sessions->signatures->validate('11111111-2222-3333-4444-555555555555', 'feature_signature', [\n    'signature_id' => '0e6c2a8e-6c2f-4b8e-9a51-3f2f6a7d9b10',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.signatures.validate(\n  \"11111111-2222-3333-4444-555555555555\",\n  \"feature_signature\",\n  signature_id: \"0e6c2a8e-6c2f-4b8e-9a51-3f2f6a7d9b10\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.Signatures.ValidateAsync(\"11111111-2222-3333-4444-555555555555\", \"feature_signature\", new SessionsSignaturesValidateParams\n{\n    SignatureId = \"0e6c2a8e-6c2f-4b8e-9a51-3f2f6a7d9b10\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/document-ai/{sessionId}/documents/{documentUuid}/": {
      "patch": {
        "summary": "Perbarui dokumen Document AI",
        "description": "Koreksi kolom yang diekstrak oleh Document AI dari satu dokumen yang diunggah, tetapkan status peninjauannya, atau keduanya, pada sesi KYC atau KYB. `extracted_data` harus berupa objek JSON dan digabungkan kunci per kunci: kunci yang Anda kirim menggantikan nilai yang tersimpan (kunci yang dikirim sebagai `null` disimpan sebagai `null`) dan kunci yang Anda abaikan tetap mempertahankan nilainya. Status dokumen memengaruhi hasil Document AI dari node alur kerjanya dalam keputusan sesi; status sesi itu sendiri tidak dihitung ulang. Setiap panggilan yang berhasil, termasuk yang tidak mengubah apa pun, mengirimkan [webhook](https://docs.didit.me/id/integration/webhooks) `data.updated` dengan pemicu `manual_review`. Kunci API dengan cakupan yang sesuai memerlukan `decisions: write`; lihat [Document AI](https://docs.didit.me/id/core-technology/document-ai/overview).",
        "operationId": "patch_v3_document_ai_document",
        "x-didit-sdk": {
          "resource": "sessions",
          "method": "update_document_ai_data",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Sessions"
        ],
        "parameters": [
          {
            "name": "sessionId",
            "in": "path",
            "required": true,
            "description": "UUID sesi verifikasi (`session_id` yang dikembalikan oleh `POST /v3/session/`). Menerima ID sesi Verifikasi Pengguna (KYC) dan Verifikasi Bisnis (KYB): server mencari ID tersebut di kedua jenis sesi. Harus berupa UUID dengan format yang benar; nilai yang salah format tidak cocok dengan rute dan mengembalikan HTML `404`.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "11111111-2222-3333-4444-555555555555"
            }
          },
          {
            "name": "documentUuid",
            "in": "path",
            "required": true,
            "description": "UUID dokumen Document AI (`document_ai_documents[].items[].uuid` di `GET /v3/session/{sessionId}/decision/`). Dokumen ini harus dimiliki oleh sesi di path tersebut.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "44444444-5555-6666-7777-888888888888"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "extracted_data": {
                    "type": "object",
                    "additionalProperties": true,
                    "description": "Kunci kolom (kunci yang Anda konfigurasi untuk dokumen) beserta nilai koreksinya. Harus berupa objek JSON; digabungkan kunci demi kunci ke dalam data yang disimpan. Jangan sertakan; jangan kirim `null`, yang akan mengembalikan `400`.",
                    "example": {
                      "invoice_number": "INV-2026-0042"
                    }
                  },
                  "status": {
                    "type": "string",
                    "enum": [
                      "Approved",
                      "Declined",
                      "In Review",
                      "Not Finished"
                    ],
                    "description": "Status peninjauan baru dari dokumen.",
                    "example": "Approved"
                  }
                }
              },
              "example": {
                "extracted_data": {
                  "invoice_number": "INV-2026-0042"
                },
                "status": "Approved"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X PATCH 'https://verification.didit.me/v3/document-ai/11111111-2222-3333-4444-555555555555/documents/44444444-5555-6666-7777-888888888888/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"extracted_data\": {\"invoice_number\": \"INV-2026-0042\"}, \"status\": \"Approved\"}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.update_document_ai_data(\n    \"11111111-2222-3333-4444-555555555555\",\n    \"44444444-5555-6666-7777-888888888888\",\n    extracted_data={\"invoice_number\": \"INV-2026-0042\"},\n    status=\"Approved\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.updateDocumentAiData(\n  \"11111111-2222-3333-4444-555555555555\",\n  \"44444444-5555-6666-7777-888888888888\",\n  {\n    extracted_data: { invoice_number: \"INV-2026-0042\" },\n    status: \"Approved\",\n  },\n);\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.UpdateDocumentAiData(ctx, \"11111111-2222-3333-4444-555555555555\", \"44444444-5555-6666-7777-888888888888\", didit.SessionsUpdateDocumentAiDataParams{\n\tExtractedData: didit.Some(map[string]any{\"invoice_number\": \"INV-2026-0042\"}),\n\tStatus:        didit.Some(didit.SessionsUpdateDocumentAiDataParamsStatus(\"Approved\")),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.SessionsUpdateDocumentAiDataParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().updateDocumentAiData(\"11111111-2222-3333-4444-555555555555\", \"44444444-5555-6666-7777-888888888888\", SessionsUpdateDocumentAiDataParams.builder()\n        .extractedData(Map.of(\"invoice_number\", \"INV-2026-0042\"))\n        .status(SessionsUpdateDocumentAiDataParams.Status.of(\"Approved\"))\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->sessions->updateDocumentAiData('11111111-2222-3333-4444-555555555555', '44444444-5555-6666-7777-888888888888', [\n    'extracted_data' => ['invoice_number' => 'INV-2026-0042'],\n    'status' => 'Approved',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.update_document_ai_data(\n  \"11111111-2222-3333-4444-555555555555\",\n  \"44444444-5555-6666-7777-888888888888\",\n  extracted_data: { invoice_number: \"INV-2026-0042\" },\n  status: \"Approved\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.UpdateDocumentAiDataAsync(\"11111111-2222-3333-4444-555555555555\", \"44444444-5555-6666-7777-888888888888\", new SessionsUpdateDocumentAiDataParams\n{\n    ExtractedData = new Dictionary<string, object> { [\"invoice_number\"] = \"INV-2026-0042\" },\n    Status = new SessionsUpdateDocumentAiDataParamsStatus(\"Approved\"),\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "Dokumen diperbarui. Mengembalikan dokumen setelah penggabungan.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "uuid",
                    "document_key",
                    "original_filename",
                    "file_url",
                    "status",
                    "extracted_data"
                  ],
                  "properties": {
                    "uuid": {
                      "type": "string",
                      "format": "uuid",
                      "description": "Pengidentifikasi dokumen."
                    },
                    "document_key": {
                      "type": "string",
                      "description": "Dokumen terkonfigurasi yang sesuai dengan unggahan ini."
                    },
                    "original_filename": {
                      "type": "string",
                      "nullable": true,
                      "description": "Nama file saat dokumen diunggah."
                    },
                    "file_url": {
                      "type": "string",
                      "nullable": true,
                      "description": "Jalur penyimpanan file yang diunggah. Ini bukan tautan unduhan: baca `file_url` yang telah ditandatangani sebelumnya dari keputusan sesi untuk mengunduh file."
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "Not Finished",
                        "Approved",
                        "Declined",
                        "In Review",
                        "Resub Requested"
                      ],
                      "description": "Status peninjauan dokumen."
                    },
                    "extracted_data": {
                      "type": "object",
                      "nullable": true,
                      "additionalProperties": true,
                      "description": "Semua kolom yang diekstrak setelah penggabungan, dengan kunci berdasarkan kunci kolom."
                    }
                  }
                },
                "example": {
                  "uuid": "44444444-5555-6666-7777-888888888888",
                  "document_key": "invoice",
                  "original_filename": "invoice-2026-09.pdf",
                  "file_url": "document_ai/11111111-2222-3333-4444-555555555555-66666666-7777-8888-9999-000000000000.pdf",
                  "status": "Approved",
                  "extracted_data": {
                    "invoice_number": "INV-2026-0042",
                    "total_amount": 1250.0,
                    "issue_date": "2026-09-01"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Kesalahan validasi, diperiksa sebelum dokumen dicari: `status` bukan salah satu dari nilai yang diizinkan, atau `extracted_data` dikirim sebagai `null`.",
            "content": {
              "application/json": {
                "examples": {
                  "Invalid status": {
                    "summary": "status tidak ada di dalam enum",
                    "value": {
                      "status": [
                        "\"Rejected\" is not a valid choice."
                      ]
                    }
                  },
                  "Null extracted_data": {
                    "summary": "extracted_data bernilai null",
                    "value": {
                      "extracted_data": [
                        "This field may not be null."
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Kunci API dengan cakupan terbatas telah kedaluwarsa. Ini satu-satunya kasus yang mengembalikan `401`: kunci yang hilang, tidak valid, atau dicabut mengembalikan `403`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "Pesan kesalahan yang mudah dibaca manusia."
                    }
                  }
                },
                "examples": {
                  "Expired key": {
                    "summary": "Tanggal kedaluwarsa kunci telah lewat",
                    "value": {
                      "detail": "This API key has expired."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Kegagalan autentikasi atau otorisasi. Kunci yang hilang mengembalikan `403`, begitu juga dengan kunci dari aplikasi lain, kunci dengan cakupan tanpa izin yang dibutuhkan endpoint ini, dan permintaan dari luar daftar izin IP kunci tersebut; kunci yang salah, dicabut, atau kedaluwarsa mengembalikan `401`. Bedakan kegagalan tersebut berdasarkan `detail`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "Pesan kesalahan yang mudah dibaca manusia."
                    }
                  }
                },
                "examples": {
                  "Missing or invalid credentials": {
                    "summary": "Tidak ada header x-api-key, atau kunci gagal divalidasi",
                    "value": {
                      "detail": "Authentication credentials were not provided or are invalid."
                    }
                  },
                  "Other application": {
                    "summary": "Kunci valid milik aplikasi yang berbeda dari sesi",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Scoped key without decisions write": {
                    "summary": "Kunci ber-scope tidak memiliki decisions: write",
                    "value": {
                      "detail": "This API key has no write access to decisions."
                    }
                  },
                  "IP not allowed": {
                    "summary": "Permintaan dari luar daftar izin IP kunci",
                    "value": {
                      "detail": "This API key can't be used from this IP address."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Sesi tidak ada, telah dihapus, atau berada di luar batas kunci dengan cakupan terbatas, atau tidak ada dokumen saat ini dengan UUID ini yang menjadi miliknya. Pencarian sesi berjalan sebelum pemeriksaan kredensial, sehingga `sessionId` yang tidak dikenal mengembalikan `404` bahkan tanpa kunci yang valid.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "Pesan kesalahan yang mudah dibaca manusia."
                    }
                  }
                },
                "examples": {
                  "Unknown session": {
                    "summary": "Tidak ada sesi dengan ID ini, atau telah dihapus",
                    "value": {
                      "detail": "Not found."
                    }
                  },
                  "Outside key limits": {
                    "summary": "Sesi berada di luar batas kunci dengan cakupan terbatas (juga dikembalikan untuk sesi yang baru saja dihapus)",
                    "value": {
                      "detail": "Session not found."
                    }
                  },
                  "Unknown document": {
                    "summary": "documentUuid bukan milik sesi",
                    "value": {
                      "detail": "Document AI document not found."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Batas laju terlampaui: 300 permintaan penulisan (POST, PATCH, DELETE) per menit per kunci API. Tunggu selama `Retry-After` detik sebelum mencoba lagi; header `X-RateLimit-*` menunjukkan anggaran tersebut.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "Pesan kesalahan yang mudah dibaca manusia."
                    }
                  }
                },
                "examples": {
                  "Rate limited": {
                    "summary": "Anggaran untuk menit saat ini habis",
                    "value": {
                      "detail": "Write request rate limit exceeded. You can make up to 300 requests per minute."
                    }
                  }
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Detik untuk menunggu sebelum mencoba lagi.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "example": 30
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/aml/dataset-freshness/": {
      "get": {
        "summary": "Dapatkan keterkinian himpunan data AML",
        "description": "Laporkan seberapa mutakhir set data di balik Skrining AML, per kelompok sumber (`sanctions`, `pep`, `warnings`, `adverse_media`), sebagai bukti audit untuk [Pemantauan AML Berkelanjutan](https://docs.didit.me/id/core-technology/aml-screening/continuous-monitoring-aml-screening#membuktikan-bahwa-pemantauan-berjalan). Jawabannya berlaku untuk seluruh platform: tidak ada sesi di path, tidak ada data pelanggan di body, jawaban yang sama untuk setiap aplikasi.\n\nSelalu `200` untuk kunci yang diterima. Periksa `availability` terlebih dahulu: jika nilainya bukan `available`, `dataset_freshness` bernilai `null`. Tanggal tidak pernah diestimasi: kelompok yang set datanya tidak melaporkan tanggal tidak akan ada di `sources`, dan kelompok yang hanya beberapa set datanya melaporkan tanggal memiliki `oldest_updated_at: null`. Pembacaan diambil saat pemantauan berkelanjutan berjalan, bukan pada setiap panggilan; `captured_at` menyatakan waktunya.\n\nKunci API dengan cakupan memerlukan `sessions: read`; kunci yang terbatas pada beberapa alur kerja atau pada sesi yang disetujui tidak dapat memanggil endpoint ini. Tidak ada yang ditagihkan.",
        "operationId": "get_aml_dataset_freshness",
        "x-didit-sdk": {
          "resource": "aml",
          "method": "retrieve_dataset_freshness",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Standalone APIs"
        ],
        "parameters": [],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/aml/dataset-freshness/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.aml.retrieve_dataset_freshness()\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.aml.retrieveDatasetFreshness();\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.AML.RetrieveDatasetFreshness(ctx)\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.aml().retrieveDatasetFreshness();\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->aml->retrieveDatasetFreshness();\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.aml.retrieve_dataset_freshness\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Aml.RetrieveDatasetFreshnessAsync();\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "Pembacaan terbaru terkait kebaruan set data, atau `null` beserta alasannya.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "dataset_freshness",
                    "availability"
                  ],
                  "properties": {
                    "dataset_freshness": {
                      "allOf": [
                        {
                          "$ref": "#/components/schemas/AMLDatasetFreshness"
                        }
                      ],
                      "nullable": true,
                      "description": "Pembacaan terbaru, atau `null` saat `availability` bukan `available`."
                    },
                    "availability": {
                      "type": "string",
                      "enum": [
                        "available",
                        "not_configured",
                        "not_yet_collected"
                      ],
                      "description": "`available` ketika pembacaan ada; `not_configured` ketika tanggal dataset tidak dikumpulkan di lingkungan ini; `not_yet_collected` ketika pengumpulan telah disiapkan tetapi belum ada pembacaan."
                    }
                  }
                },
                "examples": {
                  "Available": {
                    "value": {
                      "dataset_freshness": {
                        "captured_at": "2026-10-17T06:00:12.345678+00:00",
                        "provider": "aml_data_source",
                        "catalog_version": "20261017054500-abc",
                        "sources": {
                          "sanctions": {
                            "last_updated_at": "2026-10-17T04:10:00+00:00",
                            "oldest_updated_at": "2026-10-15T22:30:00+00:00",
                            "dataset_count": 48,
                            "dated_dataset_count": 48
                          },
                          "pep": {
                            "last_updated_at": "2026-10-16T23:05:00+00:00",
                            "oldest_updated_at": null,
                            "dataset_count": 12,
                            "dated_dataset_count": 11
                          }
                        }
                      },
                      "availability": "available"
                    }
                  },
                  "Not collected yet": {
                    "value": {
                      "dataset_freshness": null,
                      "availability": "not_yet_collected"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Kunci API telah kedaluwarsa. Hanya kunci yang dibuat dengan tanggal kedaluwarsa yang dapat kedaluwarsa; setelah tanggal tersebut, setiap permintaan dengannya menghasilkan respons `401`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Expired key": {
                    "value": {
                      "detail": "This API key has expired."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Permintaan tidak diizinkan. Kunci yang tidak ada akan mendapatkan pesan umum; kunci yang salah, dicabut, atau kedaluwarsa akan mendapatkan `401`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Missing or invalid key": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Scoped key without sessions read": {
                    "value": {
                      "detail": "This API key has no read access to sessions."
                    }
                  },
                  "Key limited to workflows or approved sessions": {
                    "value": {
                      "detail": "This API key only reaches sessions inside its workflow or status limits, so it can't use this endpoint."
                    }
                  },
                  "Outside the key's IP list": {
                    "value": {
                      "detail": "This API key can't be used from this IP address."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Lebih dari 600 permintaan GET per menit dengan kunci API ini. Tunggu selama jumlah detik di `Retry-After`, lalu coba lagi.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Throttled": {
                    "value": {
                      "detail": "GET request rate limit exceeded. You can make up to 600 requests per minute."
                    }
                  }
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Detik hingga jendela satu menit saat ini direset.",
                "schema": {
                  "type": "integer",
                  "example": 23
                }
              },
              "X-RateLimit-Limit": {
                "description": "Permintaan yang diizinkan per menit dalam anggaran ini.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Permintaan tersisa dalam jendela saat ini.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Waktu Unix saat jendela direset.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/lists/": {
      "get": {
        "summary": "Mencantumkan daftar",
        "description": "Mengembalikan daftar milik aplikasi, yang terbaru terlebih dahulu: daftar sistem yang disediakan Didit (satu daftar blokir per jenis entri, daftar kustom **High Risk Countries**, dan allowlist sistem apa pun) serta allowlist dan daftar kustom yang Anda buat. Filter dengan `list_type` dan `entry_type`; daftar yang dihapus tidak akan pernah muncul. Hasil dipaginasi dengan `limit` dan `offset`. Kunci API ber-scope memerlukan `workflows: read`. Lihat [Daftar](https://docs.didit.me/id/management-api/lists/overview) untuk mengetahui fungsi masing-masing jenis daftar.",
        "operationId": "list_lists",
        "x-didit-sdk": {
          "resource": "lists",
          "method": "list",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Lists"
        ],
        "parameters": [
          {
            "name": "list_type",
            "in": "query",
            "required": false,
            "description": "Hanya daftar dari jenis ini.",
            "schema": {
              "type": "string",
              "enum": [
                "blocklist",
                "allowlist",
                "custom"
              ]
            }
          },
          {
            "name": "entry_type",
            "in": "query",
            "required": false,
            "description": "Hanya daftar entri jenis ini.",
            "schema": {
              "type": "string",
              "enum": [
                "face",
                "document",
                "phone",
                "email",
                "ip_address",
                "device_fingerprint",
                "wallet_address",
                "bank_account",
                "country",
                "user",
                "business",
                "key"
              ]
            }
          },
          {
            "name": "ordering",
            "in": "query",
            "required": false,
            "description": "Urutan pengurutan: `-created_at` (terbaru terlebih dahulu, default) atau `created_at` (terlama terlebih dahulu).",
            "schema": {
              "type": "string",
              "enum": [
                "-created_at",
                "created_at"
              ],
              "default": "-created_at"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Ukuran halaman. Nilai default-nya 50. Nilai di atas 1000000 mengembalikan `400`; nol, nilai negatif, atau nilai non-numerik akan kembali ke 50.",
            "schema": {
              "type": "integer",
              "default": 50,
              "minimum": 1,
              "maximum": 1000000
            }
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "description": "Indeks berbasis nol dari item pertama yang dikembalikan. Sebaiknya ikuti `next`. Nilai di atas 1000000 mengembalikan `400`; nilai negatif atau non-numerik akan kembali ke 0.",
            "schema": {
              "type": "integer",
              "default": 0,
              "minimum": 0,
              "maximum": 1000000
            }
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/lists/?list_type=blocklist' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nfor item in client.lists.list():\n    print(item)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nfor await (const item of didit.lists.list()) {\n  console.log(item);\n}"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\niter := client.Lists.ListAutoPaging(ctx, didit.ListsListParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nfor (var item : client.lists().list()) {\n    System.out.println(item);\n}"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\nforeach ($didit->lists->list() as $item) {\n    print_r($item->toArray());\n}"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.lists.list.auto_paging_each do |item|\n  puts item.to_h\nend"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.Lists.ListAsync())\n{\n    Console.WriteLine(JsonSerializer.Serialize(item));\n}"
          }
        ],
        "responses": {
          "200": {
            "description": "Satu halaman daftar.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "count",
                    "next",
                    "previous",
                    "results"
                  ],
                  "properties": {
                    "count": {
                      "type": "integer",
                      "minimum": 0,
                      "description": "Jumlah total daftar yang cocok dengan filter."
                    },
                    "next": {
                      "type": "string",
                      "format": "uri",
                      "nullable": true,
                      "description": "URL absolut halaman berikutnya, atau `null` di halaman terakhir."
                    },
                    "previous": {
                      "type": "string",
                      "format": "uri",
                      "nullable": true,
                      "description": "URL absolut halaman sebelumnya, atau `null` di halaman pertama."
                    },
                    "results": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/ComplianceList"
                      }
                    }
                  }
                },
                "examples": {
                  "Lists": {
                    "value": {
                      "count": 2,
                      "next": null,
                      "previous": null,
                      "results": [
                        {
                          "uuid": "22222222-3333-4444-5555-666666666666",
                          "name": "Trusted office IPs",
                          "description": "Office egress ranges",
                          "list_type": "allowlist",
                          "entry_type": "ip_address",
                          "is_system": false,
                          "entry_count": 3,
                          "last_entry_added_at": "2026-10-02T08:15:27.501334Z",
                          "created_at": "2026-09-30T13:20:45.889120Z",
                          "updated_at": "2026-09-30T13:20:45.889120Z"
                        },
                        {
                          "uuid": "11111111-2222-3333-4444-555555555555",
                          "name": "Face Blocklist",
                          "description": "Blocked biometric faces. When a face matching an entry in this list is detected during liveness verification, the session will be automatically declined.",
                          "list_type": "blocklist",
                          "entry_type": "face",
                          "is_system": true,
                          "entry_count": 12,
                          "last_entry_added_at": "2026-10-09T16:42:03.118204Z",
                          "created_at": "2026-01-14T10:02:11.402917Z",
                          "updated_at": "2026-01-14T10:02:11.402917Z"
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Parameter kueri tidak valid.",
            "content": {
              "application/json": {
                "examples": {
                  "Unknown list type": {
                    "value": {
                      "list_type": [
                        "\"denylist\" is not a valid choice."
                      ]
                    }
                  },
                  "Unsupported ordering": {
                    "value": {
                      "ordering": [
                        "\"name\" is not a valid choice."
                      ]
                    }
                  },
                  "Limit too large": {
                    "value": [
                      "limit must not exceed 1000000."
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Kunci API dengan cakupan terbatas telah kedaluwarsa. Kegagalan autentikasi lainnya mengembalikan `403`.",
            "content": {
              "application/json": {
                "examples": {
                  "Expired API key": {
                    "value": {
                      "detail": "This API key has expired."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Header `x-api-key` tidak ada (kunci yang salah, dicabut, atau kedaluwarsa menghasilkan `401`), atau kunci API dengan cakupan tertentu tidak memiliki `workflows: read` atau digunakan dari alamat IP di luar daftar izinnya.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing or invalid API key": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Scoped key without workflows access": {
                    "value": {
                      "detail": "This API key has no read access to workflows."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Batas baca bersama sebesar 600 permintaan per menit per kunci API telah terlampaui. Patuhi `Retry-After` sebelum mencoba lagi.",
            "content": {
              "application/json": {
                "examples": {
                  "Rate limited": {
                    "value": {
                      "detail": "GET request rate limit exceeded. You can make up to 600 requests per minute."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      },
      "post": {
        "summary": "Buat daftar",
        "description": "Membuat allowlist atau daftar kustom dalam aplikasi yang memiliki kunci API tersebut. Daftar blokir tidak dapat dibuat: Didit menyediakan satu daftar blokir sistem per jenis entri, dan Anda menambahkannya dengan [Buat entri daftar](https://docs.didit.me/id/management-api/lists/create-entry). `entry_type` tidak dapat diubah setelah pembuatan dan menentukan bagaimana nilai entri divalidasi dan dicocokkan. Entri allowlist menandai item yang cocok sebagai tepercaya (misalnya, allowlist wajah melewati tindakan wajah duplikat) dan tidak pernah mengesampingkan kecocokan daftar blokir; rujuk daftar apa pun dalam kondisi aturan alur kerja atau aturan transaksi dengan `value_type: \"list\"`. Kunci API dengan cakupan memerlukan `workflows: write`.",
        "operationId": "create_list",
        "x-didit-sdk": {
          "resource": "lists",
          "method": "create",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Lists"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "name",
                  "list_type",
                  "entry_type"
                ],
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 255,
                    "description": "Nama daftar. Harus berbeda dari nama setiap daftar lain di aplikasi, termasuk daftar sistem."
                  },
                  "description": {
                    "type": "string",
                    "default": "",
                    "description": "Deskripsi teks bebas opsional."
                  },
                  "list_type": {
                    "type": "string",
                    "enum": [
                      "allowlist",
                      "custom"
                    ],
                    "description": "`allowlist` atau `custom`. `blocklist` ditolak dengan kode `400`."
                  },
                  "entry_type": {
                    "type": "string",
                    "enum": [
                      "face",
                      "document",
                      "phone",
                      "email",
                      "ip_address",
                      "device_fingerprint",
                      "wallet_address",
                      "bank_account",
                      "country",
                      "user",
                      "business",
                      "key"
                    ],
                    "description": "Apa yang dimuat dalam daftar: `face`, `document` (nomor dokumen), `phone`, `email`, `ip_address` (alamat atau rentang CIDR), `device_fingerprint`, `wallet_address`, `bank_account`, `country` (ISO 3166-1 alpha-3), `user` atau `business` (`vendor_data` Anda), atau `key` (string apa pun). Ini menentukan cara nilai entri divalidasi dan dicocokkan. Tidak dapat diubah nanti."
                  }
                }
              },
              "examples": {
                "IP allowlist": {
                  "value": {
                    "name": "Trusted office IPs",
                    "description": "Office egress ranges",
                    "list_type": "allowlist",
                    "entry_type": "ip_address"
                  }
                },
                "Custom country list": {
                  "value": {
                    "name": "Enhanced due diligence countries",
                    "list_type": "custom",
                    "entry_type": "country"
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://verification.didit.me/v3/lists/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"name\": \"Trusted office IPs\",\n    \"description\": \"Office egress ranges\",\n    \"list_type\": \"allowlist\",\n    \"entry_type\": \"ip_address\"\n  }'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.lists.create(\n    name=\"Trusted office IPs\",\n    description=\"Office egress ranges\",\n    list_type=\"allowlist\",\n    entry_type=\"ip_address\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.lists.create({\n  name: \"Trusted office IPs\",\n  description: \"Office egress ranges\",\n  list_type: \"allowlist\",\n  entry_type: \"ip_address\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Lists.Create(ctx, didit.ListsCreateParams{\n\tName:        \"Trusted office IPs\",\n\tDescription: didit.String(\"Office egress ranges\"),\n\tListType:    \"allowlist\",\n\tEntryType:   \"ip_address\",\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.ListsCreateParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.lists().create(ListsCreateParams.builder()\n        .name(\"Trusted office IPs\")\n        .description(\"Office egress ranges\")\n        .listType(ListsCreateParams.ListType.of(\"allowlist\"))\n        .entryType(ListsCreateParams.EntryType.of(\"ip_address\"))\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->lists->create([\n    'name' => 'Trusted office IPs',\n    'description' => 'Office egress ranges',\n    'list_type' => 'allowlist',\n    'entry_type' => 'ip_address',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.lists.create(\n  name: \"Trusted office IPs\",\n  description: \"Office egress ranges\",\n  list_type: \"allowlist\",\n  entry_type: \"ip_address\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Lists.CreateAsync(new ListsCreateParams\n{\n    Name = \"Trusted office IPs\",\n    Description = \"Office egress ranges\",\n    ListType = \"allowlist\",\n    EntryType = \"ip_address\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "201": {
            "description": "Daftar telah dibuat.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ComplianceList"
                },
                "examples": {
                  "New allowlist": {
                    "value": {
                      "uuid": "22222222-3333-4444-5555-666666666666",
                      "name": "Trusted office IPs",
                      "description": "Office egress ranges",
                      "list_type": "allowlist",
                      "entry_type": "ip_address",
                      "is_system": false,
                      "entry_count": 0,
                      "last_entry_added_at": null,
                      "created_at": "2026-10-12T09:15:44.031876Z",
                      "updated_at": "2026-10-12T09:15:44.031876Z"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Isi permintaan tidak valid.",
            "content": {
              "application/json": {
                "examples": {
                  "Blocklist refused": {
                    "value": {
                      "list_type": [
                        "Cannot create additional blocklist lists. System blocklists are auto-created for each application."
                      ]
                    }
                  },
                  "Duplicate name": {
                    "value": {
                      "name": [
                        "A list with this name already exists for this application."
                      ]
                    }
                  },
                  "Missing fields": {
                    "value": {
                      "name": [
                        "This field is required."
                      ],
                      "list_type": [
                        "This field is required."
                      ],
                      "entry_type": [
                        "This field is required."
                      ]
                    }
                  },
                  "Unknown entry type": {
                    "value": {
                      "entry_type": [
                        "\"iban\" is not a valid choice."
                      ]
                    }
                  },
                  "Name too long": {
                    "value": {
                      "name": [
                        "Ensure this field has no more than 255 characters."
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Kunci API dengan cakupan terbatas telah kedaluwarsa. Kegagalan autentikasi lainnya mengembalikan `403`.",
            "content": {
              "application/json": {
                "examples": {
                  "Expired API key": {
                    "value": {
                      "detail": "This API key has expired."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Header `x-api-key` tidak ada (kunci yang salah, dicabut, atau kedaluwarsa menghasilkan `401`), atau kunci API dengan cakupan tertentu tidak memiliki `workflows: write` atau digunakan dari alamat IP di luar daftar izinnya.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing or invalid API key": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Scoped key without workflows access": {
                    "value": {
                      "detail": "This API key has no write access to workflows."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimitedWrite"
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/lists/{list_uuid}/": {
      "get": {
        "summary": "Dapatkan daftar",
        "description": "Mengembalikan satu daftar dari aplikasi beserta jumlah entri dan waktu entri terbarunya ditambahkan. Daftar milik aplikasi lain, atau yang telah dihapus, mengembalikan `404`. Ini hanya mengembalikan daftar tersebut: baca nilai-nilainya dengan [Cantumkan entri daftar](https://docs.didit.me/id/management-api/lists/list-entries). Kunci API dengan cakupan memerlukan `workflows: read`.",
        "operationId": "get_list",
        "x-didit-sdk": {
          "resource": "lists",
          "method": "retrieve",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Lists"
        ],
        "parameters": [
          {
            "name": "list_uuid",
            "in": "path",
            "required": true,
            "description": "UUID daftar, seperti yang dikembalikan oleh Cantumkan daftar atau Buat daftar.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "11111111-2222-3333-4444-555555555555"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/lists/11111111-2222-3333-4444-555555555555/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.lists.retrieve(\n    \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.lists.retrieve(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Lists.Retrieve(ctx, \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.lists().retrieve(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->lists->retrieve('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.lists.retrieve(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Lists.RetrieveAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "Daftar tersebut.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ComplianceList"
                },
                "examples": {
                  "System face blocklist": {
                    "value": {
                      "uuid": "11111111-2222-3333-4444-555555555555",
                      "name": "Face Blocklist",
                      "description": "Blocked biometric faces. When a face matching an entry in this list is detected during liveness verification, the session will be automatically declined.",
                      "list_type": "blocklist",
                      "entry_type": "face",
                      "is_system": true,
                      "entry_count": 12,
                      "last_entry_added_at": "2026-10-09T16:42:03.118204Z",
                      "created_at": "2026-01-14T10:02:11.402917Z",
                      "updated_at": "2026-01-14T10:02:11.402917Z"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Kunci API dengan cakupan terbatas telah kedaluwarsa. Kegagalan autentikasi lainnya mengembalikan `403`.",
            "content": {
              "application/json": {
                "examples": {
                  "Expired API key": {
                    "value": {
                      "detail": "This API key has expired."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Header `x-api-key` tidak ada (kunci yang salah, dicabut, atau kedaluwarsa menghasilkan `401`), atau kunci API dengan cakupan tertentu tidak memiliki `workflows: read` atau digunakan dari alamat IP di luar daftar izinnya.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing or invalid API key": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Scoped key without workflows access": {
                    "value": {
                      "detail": "This API key has no read access to workflows."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Tidak ada daftar dengan UUID ini di aplikasi milik kunci API, atau daftar tersebut telah dihapus.",
            "content": {
              "application/json": {
                "examples": {
                  "Not found": {
                    "value": {
                      "detail": "No List matches the given query."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Batas baca bersama sebesar 600 permintaan per menit per kunci API telah terlampaui. Patuhi `Retry-After` sebelum mencoba lagi.",
            "content": {
              "application/json": {
                "examples": {
                  "Rate limited": {
                    "value": {
                      "detail": "GET request rate limit exceeded. You can make up to 600 requests per minute."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      },
      "patch": {
        "summary": "Perbarui daftar",
        "description": "Mengubah nama daftar atau mengubah deskripsinya. Hanya `name` dan `description` yang dibaca; kolom lainnya diabaikan, sehingga `list_type` dan `entry_type` tetap mempertahankan nilai saat dibuat. Daftar sistem tidak dapat dimodifikasi dan mengembalikan `400`. Respons hanya berisi `name` dan `description`: panggil [Dapatkan daftar](https://docs.didit.me/id/management-api/lists/get) untuk daftar lengkapnya. Kunci API terbatas memerlukan `workflows: write`.",
        "operationId": "update_list",
        "x-didit-sdk": {
          "resource": "lists",
          "method": "update",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Lists"
        ],
        "parameters": [
          {
            "name": "list_uuid",
            "in": "path",
            "required": true,
            "description": "UUID daftar, seperti yang dikembalikan oleh Cantumkan daftar atau Buat daftar.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "11111111-2222-3333-4444-555555555555"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 255,
                    "description": "Nama baru. Harus berbeda dari nama setiap daftar lain pada aplikasi."
                  },
                  "description": {
                    "type": "string",
                    "description": "Deskripsi baru. Kirim string kosong untuk menghapusnya."
                  }
                }
              },
              "examples": {
                "Rename": {
                  "value": {
                    "name": "Trusted office and VPN IPs"
                  }
                },
                "Rename and describe": {
                  "value": {
                    "name": "Trusted office and VPN IPs",
                    "description": "Office egress ranges and the corporate VPN"
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X PATCH 'https://verification.didit.me/v3/lists/11111111-2222-3333-4444-555555555555/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"name\": \"Trusted office and VPN IPs\"}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.lists.update(\n    \"11111111-2222-3333-4444-555555555555\",\n    name=\"Trusted office and VPN IPs\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.lists.update(\"11111111-2222-3333-4444-555555555555\", {\n  name: \"Trusted office and VPN IPs\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Lists.Update(ctx, \"11111111-2222-3333-4444-555555555555\", didit.ListsUpdateParams{\n\tName: didit.String(\"Trusted office and VPN IPs\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.ListsUpdateParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.lists().update(\"11111111-2222-3333-4444-555555555555\", ListsUpdateParams.builder()\n        .name(\"Trusted office and VPN IPs\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->lists->update('11111111-2222-3333-4444-555555555555', [\n    'name' => 'Trusted office and VPN IPs',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.lists.update(\n  \"11111111-2222-3333-4444-555555555555\",\n  name: \"Trusted office and VPN IPs\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Lists.UpdateAsync(\"11111111-2222-3333-4444-555555555555\", new ListsUpdateParams\n{\n    Name = \"Trusted office and VPN IPs\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "Daftar telah diperbarui. Hanya kolom yang dapat diedit yang dikembalikan.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "name",
                    "description"
                  ],
                  "properties": {
                    "name": {
                      "type": "string",
                      "description": "Nama daftar setelah pembaruan."
                    },
                    "description": {
                      "type": "string",
                      "description": "Deskripsi daftar setelah pembaruan."
                    }
                  }
                },
                "examples": {
                  "Renamed": {
                    "value": {
                      "name": "Trusted office and VPN IPs",
                      "description": "Office egress ranges"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Daftar ini adalah daftar sistem, atau isi permintaan tidak valid.",
            "content": {
              "application/json": {
                "examples": {
                  "System list": {
                    "value": {
                      "non_field_errors": [
                        "System lists cannot be modified."
                      ]
                    }
                  },
                  "Duplicate name": {
                    "value": {
                      "name": [
                        "A list with this name already exists for this application."
                      ]
                    }
                  },
                  "Blank name": {
                    "value": {
                      "name": [
                        "This field may not be blank."
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Kunci API dengan cakupan terbatas telah kedaluwarsa. Kegagalan autentikasi lainnya mengembalikan `403`.",
            "content": {
              "application/json": {
                "examples": {
                  "Expired API key": {
                    "value": {
                      "detail": "This API key has expired."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Header `x-api-key` tidak ada (kunci yang salah, dicabut, atau kedaluwarsa menghasilkan `401`), atau kunci API dengan cakupan tertentu tidak memiliki `workflows: write` atau digunakan dari alamat IP di luar daftar izinnya.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing or invalid API key": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Scoped key without workflows access": {
                    "value": {
                      "detail": "This API key has no write access to workflows."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Tidak ada daftar dengan UUID ini di aplikasi milik kunci API, atau daftar tersebut telah dihapus.",
            "content": {
              "application/json": {
                "examples": {
                  "Not found": {
                    "value": {
                      "detail": "No List matches the given query."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimitedWrite"
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      },
      "delete": {
        "summary": "Hapus daftar",
        "description": "Menghapus daftar izin (allowlist) atau daftar kustom beserta entri-entrinya. Penghapusan tidak dapat dibatalkan: daftar dan entrinya tidak lagi muncul dalam respons pembacaan apa pun, dan kondisi aturan alur kerja dan aturan transaksi yang merujuk pada daftar tersebut akan mengevaluasinya sebagai daftar kosong sejak saat itu. Sesi dan transaksi yang telah dievaluasi tetap mempertahankan hasilnya, dan nama tersebut dapat digunakan kembali untuk daftar baru. Daftar sistem tidak dapat dihapus dan mengembalikan `400`; untuk mengosongkannya, [hapus entri-entrinya](https://docs.didit.me/id/management-api/lists/delete-entry). Kunci API dengan cakupan membutuhkan `workflows: write`.",
        "operationId": "delete_list",
        "x-didit-sdk": {
          "resource": "lists",
          "method": "delete",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Lists"
        ],
        "parameters": [
          {
            "name": "list_uuid",
            "in": "path",
            "required": true,
            "description": "UUID daftar, seperti yang dikembalikan oleh Cantumkan daftar atau Buat daftar.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "11111111-2222-3333-4444-555555555555"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X DELETE 'https://verification.didit.me/v3/lists/11111111-2222-3333-4444-555555555555/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nclient.lists.delete(\n    \"11111111-2222-3333-4444-555555555555\",\n)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nawait didit.lists.delete(\"11111111-2222-3333-4444-555555555555\");"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nif err := client.Lists.Delete(ctx, \"11111111-2222-3333-4444-555555555555\"); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nclient.lists().delete(\"11111111-2222-3333-4444-555555555555\");"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$didit->lists->delete('11111111-2222-3333-4444-555555555555');"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.lists.delete(\"11111111-2222-3333-4444-555555555555\")"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nawait client.Lists.DeleteAsync(\"11111111-2222-3333-4444-555555555555\");"
          }
        ],
        "responses": {
          "204": {
            "description": "Daftar dan entri di dalamnya telah dihapus. Tidak ada isi respons."
          },
          "400": {
            "description": "Daftar ini adalah daftar sistem.",
            "content": {
              "application/json": {
                "examples": {
                  "System list": {
                    "value": {
                      "detail": "System lists cannot be deleted."
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Kunci API dengan cakupan terbatas telah kedaluwarsa. Kegagalan autentikasi lainnya mengembalikan `403`.",
            "content": {
              "application/json": {
                "examples": {
                  "Expired API key": {
                    "value": {
                      "detail": "This API key has expired."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Header `x-api-key` tidak ada (kunci yang salah, dicabut, atau kedaluwarsa menghasilkan `401`), atau kunci API dengan cakupan tertentu tidak memiliki `workflows: write` atau digunakan dari alamat IP di luar daftar izinnya.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing or invalid API key": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Scoped key without workflows access": {
                    "value": {
                      "detail": "This API key has no write access to workflows."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Tidak ada daftar dengan UUID ini di aplikasi milik kunci API, atau daftar tersebut sudah dihapus.",
            "content": {
              "application/json": {
                "examples": {
                  "Not found": {
                    "value": {
                      "detail": "No List matches the given query."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimitedWrite"
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/lists/{list_uuid}/entries/": {
      "get": {
        "summary": "Mencantumkan entri daftar",
        "description": "Mengembalikan entri saat ini dari satu daftar, yang terbaru terlebih dahulu. `search` mencocokkan sebagian dari `value` atau `display_label` suatu entri tanpa membedakan huruf besar/kecil, dan `reference_session_id` mempersempit hasil ke entri yang diambil dari satu sesi verifikasi seseorang. URL gambar dalam `metadata` adalah URL bertanda tangan berumur pendek yang diterbitkan kembali pada setiap pemanggilan; kunci API ber-scope tanpa `media: read` menerima `null` sebagai gantinya. Kunci API ber-scope memerlukan `workflows: read`.",
        "operationId": "list_list_entries",
        "x-didit-sdk": {
          "resource": "lists.entries",
          "method": "list",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Lists"
        ],
        "parameters": [
          {
            "name": "list_uuid",
            "in": "path",
            "required": true,
            "description": "UUID daftar, seperti yang dikembalikan oleh Cantumkan daftar atau Buat daftar.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "11111111-2222-3333-4444-555555555555"
          },
          {
            "name": "search",
            "in": "query",
            "required": false,
            "description": "Teks tidak peka huruf besar/kecil yang harus termuat dalam `value` atau `display_label` entri.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "reference_session_id",
            "in": "query",
            "required": false,
            "description": "Hanya entri yang diambil dari sesi verifikasi individu ini, misalnya untuk melihat wajah mana saja miliknya yang sudah terdaftar.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Ukuran halaman. Nilai default-nya 50. Nilai di atas 1000000 mengembalikan `400`; nol, nilai negatif, atau nilai non-numerik akan kembali ke 50.",
            "schema": {
              "type": "integer",
              "default": 50,
              "minimum": 1,
              "maximum": 1000000
            }
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "description": "Indeks berbasis nol dari item pertama yang dikembalikan. Sebaiknya ikuti `next`. Nilai di atas 1000000 mengembalikan `400`; nilai negatif atau non-numerik akan kembali ke 0.",
            "schema": {
              "type": "integer",
              "default": 0,
              "minimum": 0,
              "maximum": 1000000
            }
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/lists/11111111-2222-3333-4444-555555555555/entries/?search=example.com' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nfor item in client.lists.entries.list(\n    \"11111111-2222-3333-4444-555555555555\",\n):\n    print(item)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nfor await (const item of didit.lists.entries.list(\"11111111-2222-3333-4444-555555555555\")) {\n  console.log(item);\n}"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\niter := client.Lists.Entries.ListAutoPaging(ctx, \"11111111-2222-3333-4444-555555555555\", didit.ListsEntriesListParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nfor (var item : client.lists().entries().list(\"11111111-2222-3333-4444-555555555555\")) {\n    System.out.println(item);\n}"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\nforeach ($didit->lists->entries->list('11111111-2222-3333-4444-555555555555') as $item) {\n    print_r($item->toArray());\n}"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.lists.entries.list(\"11111111-2222-3333-4444-555555555555\").auto_paging_each do |item|\n  puts item.to_h\nend"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.Lists.Entries.ListAsync(\"11111111-2222-3333-4444-555555555555\"))\n{\n    Console.WriteLine(JsonSerializer.Serialize(item));\n}"
          }
        ],
        "responses": {
          "200": {
            "description": "Satu halaman entri, yang terbaru lebih dulu.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "count",
                    "next",
                    "previous",
                    "results"
                  ],
                  "properties": {
                    "count": {
                      "type": "integer",
                      "minimum": 0,
                      "description": "Jumlah total entri yang cocok dengan filter."
                    },
                    "next": {
                      "type": "string",
                      "format": "uri",
                      "nullable": true,
                      "description": "URL absolut halaman berikutnya, atau `null` di halaman terakhir."
                    },
                    "previous": {
                      "type": "string",
                      "format": "uri",
                      "nullable": true,
                      "description": "URL absolut halaman sebelumnya, atau `null` di halaman pertama."
                    },
                    "results": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/ComplianceListEntry"
                      }
                    }
                  }
                },
                "examples": {
                  "Entries": {
                    "value": {
                      "count": 2,
                      "next": null,
                      "previous": null,
                      "results": [
                        {
                          "uuid": "bbbbbbbb-cccc-dddd-eeee-ffffffffffff",
                          "value": "X1234567",
                          "display_label": "Jane Doe - X1234567",
                          "comment": "",
                          "added_by": "api",
                          "reference_session_id": "33333333-4444-5555-6666-777777777777",
                          "reference_session_number": 1042,
                          "reference_session_type": "kyc",
                          "reference_object_uuid": "66666666-7777-8888-9999-000000000000",
                          "metadata": {
                            "full_name": "Jane Doe",
                            "issuing_state": "ESP",
                            "document_type": "ID",
                            "region": "",
                            "document_number": "X1234567"
                          },
                          "created_at": "2026-10-12T10:06:12.774915Z"
                        },
                        {
                          "uuid": "eeeeeeee-ffff-0000-1111-222222222222",
                          "value": "y7654321",
                          "display_label": "",
                          "comment": "Reported by a partner",
                          "added_by": "api",
                          "reference_session_id": null,
                          "reference_session_number": null,
                          "reference_session_type": null,
                          "reference_object_uuid": null,
                          "metadata": null,
                          "created_at": "2026-10-03T07:48:30.552810Z"
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Parameter kueri tidak valid.",
            "content": {
              "application/json": {
                "examples": {
                  "Invalid session id": {
                    "value": {
                      "reference_session_id": [
                        "Must be a valid UUID."
                      ]
                    }
                  },
                  "Limit too large": {
                    "value": [
                      "limit must not exceed 1000000."
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Kunci API dengan cakupan terbatas telah kedaluwarsa. Kegagalan autentikasi lainnya mengembalikan `403`.",
            "content": {
              "application/json": {
                "examples": {
                  "Expired API key": {
                    "value": {
                      "detail": "This API key has expired."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Header `x-api-key` tidak ada (kunci yang salah, dicabut, atau kedaluwarsa menghasilkan `401`), atau kunci API dengan cakupan tertentu tidak memiliki `workflows: read` atau digunakan dari alamat IP di luar daftar izinnya.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing or invalid API key": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Scoped key without workflows access": {
                    "value": {
                      "detail": "This API key has no read access to workflows."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Tidak ada daftar dengan UUID ini di aplikasi milik kunci API, atau daftar tersebut telah dihapus.",
            "content": {
              "application/json": {
                "examples": {
                  "Not found": {
                    "value": {
                      "detail": "List not found."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Batas baca bersama sebesar 600 permintaan per menit per kunci API telah terlampaui. Patuhi `Retry-After` sebelum mencoba lagi.",
            "content": {
              "application/json": {
                "examples": {
                  "Rate limited": {
                    "value": {
                      "detail": "GET request rate limit exceeded. You can make up to 600 requests per minute."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      },
      "post": {
        "summary": "Buat entri daftar",
        "description": "Menambahkan satu entri ke daftar, dengan salah satu dari tiga cara: berdasarkan `value`; dari sesi verifikasi dengan `reference_session_id`, tempat Didit membaca nilai dari catatan terbaru sesi dari tipe entri daftar tersebut dan menautkan entri ke sana; atau berdasarkan `value` dengan `reference_object_uuid` dan `metadata.reference_type` yang mengarah kembali ke transaksi, pengguna, atau bisnis. Pada daftar blokir sistem untuk wajah, dokumen, telepon, dan email, catatan yang dibaca dari sesi tersebut juga ditandai sebagai masuk daftar blokir, sehingga sesi pencocokan baru akan ditolak; pada daftar blokir pengguna dan bisnis sistem, pengguna atau bisnis yang cocok diatur ke `BLOCKED`. Sesi dan transaksi yang telah selesai tidak diubah. Kunci API dengan cakupan memerlukan `workflows: write`. Lihat [Membuat entri daftar](https://docs.didit.me/id/management-api/lists/create-entry) untuk setiap mode.",
        "operationId": "create_list_entry",
        "x-didit-sdk": {
          "resource": "lists.entries",
          "method": "create",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Lists"
        ],
        "parameters": [
          {
            "name": "list_uuid",
            "in": "path",
            "required": true,
            "description": "UUID daftar yang akan ditambahkan. Untuk wajah yang hanya Anda miliki dalam bentuk gambar, gunakan Unggah wajah ke daftar sebagai gantinya.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "11111111-2222-3333-4444-555555555555"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "description": "Kirim `value`, `reference_session_id`, atau keduanya. Kolom mana yang berlaku bergantung pada `entry_type` daftar tersebut.",
                "properties": {
                  "value": {
                    "type": "string",
                    "description": "Nilai yang akan dicantumkan dalam daftar, divalidasi terhadap `entry_type` daftar: `email` alamat email yang valid; `phone` nomor internasional yang valid, disimpan dalam E.164; `ip_address` alamat IP atau rentang CIDR (misalnya `10.0.0.0/8`); `device_fingerprint` setidaknya 8 karakter di antara huruf, angka, `-`, `_`, `:`, dan `.` (daftar blokir menolak sidik jari yang dilaporkan oleh beberapa perangkat berbeda); `country` kode ISO 3166-1 alpha-2 atau alpha-3, disimpan sebagai alpha-3; `user` dan `business` berupa `vendor_data`; tipe lainnya berupa string yang tidak kosong. Disimpan dalam huruf kecil kecuali nomor telepon dan kode negara, dan daftar menyimpan setiap nilai satu kali (tidak peka huruf besar/kecil). Wajib diisi kecuali jika `reference_session_id` dikirim; harus dikosongkan jika `face_image_source` menggunakan pengambilan dokumen."
                  },
                  "reference_session_id": {
                    "type": "string",
                    "format": "uuid",
                    "description": "Sesi verifikasi perorangan atau bisnis pada aplikasi Anda yang akan menjadi sumber nilai. Didit membaca rekaman terbaru sesi dari tipe entri daftar tersebut (`face`, `document`, `phone`, `email`, `ip_address` or `device_fingerprint`), menautkan entri ke sesi dan ke rekaman tersebut, serta mengisi `display_label` dan `metadata` untuk dokumen. Untuk daftar blokir `device_fingerprint`, sesi yang hanya memiliki sidik jari kelas perangkat, atau diselesaikan di lebih dari satu perangkat, akan ditolak: kirimkan sidik jari yang tepat sebagai `value`. Untuk tipe entri lain, atau ketika sesi tidak memiliki rekaman tersebut, kirimkan juga `value`; `value` Anda kemudian disimpan dan entri tetap ditautkan ke sesi."
                  },
                  "reference_object_uuid": {
                    "type": "string",
                    "format": "uuid",
                    "description": "UUID rekaman yang diwakili entri ketika tidak berasal dari suatu sesi: UUID transaksi, atau `didit_internal_id` pengguna atau bisnis. Pasangkan dengan `metadata.reference_type`. Digantikan oleh rekaman sesi ketika `reference_session_id` menyediakannya."
                  },
                  "face_image_source": {
                    "type": "string",
                    "enum": [
                      "liveness",
                      "front_image_camera_front",
                      "back_image_camera_front"
                    ],
                    "default": "liveness",
                    "description": "Daftar wajah dengan `reference_session_id`: dari gambar sesi mana wajah diambil. `liveness` (default) adalah swafoto liveness. `front_image_camera_front` dan `back_image_camera_front` adalah swafoto yang diambil kamera depan saat pengguna memotret bagian depan atau belakang dokumen mereka: hanya diterima pada daftar blokir wajah sistem, dengan `reference_session_id` dan `value` kosong. Setiap swafoto dapat ditambahkan sekali dan harus menampilkan satu wajah yang jelas."
                  },
                  "reference_node_id": {
                    "type": "string",
                    "nullable": true,
                    "maxLength": 100,
                    "description": "Dengan `face_image_source` untuk pengambilan dokumen: node Verifikasi Identitas yang swafotonya akan digunakan, untuk alur kerja yang memiliki lebih dari satu. Secara default, gunakan Verifikasi Identitas terbaru yang memiliki gambar tersebut. Ditolak jika menggunakan `liveness`."
                  },
                  "display_label": {
                    "type": "string",
                    "maxLength": 512,
                    "description": "Label yang mudah dibaca manusia. Jika kosong, Didit menurunkannya dari sesi jika memungkinkan (misalnya nama pemegang dan nomor dokumen)."
                  },
                  "comment": {
                    "type": "string",
                    "description": "Catatan teks bebas, seperti alasan pencantuman."
                  },
                  "metadata": {
                    "type": "object",
                    "additionalProperties": true,
                    "description": "JSON bentuk bebas yang disimpan bersama entri dan dikembalikan sebagaimana disimpan. Gunakan `reference_type` dan `reference_id` agar konsol menautkan kembali ke sumbernya. `reference_image_url` dan `front_image_url` hanya diatur oleh Didit dan akan diabaikan jika Anda mengirimkannya. Untuk entri yang dibaca dari suatu sesi, kunci dari Didit digabungkan dengan kunci milik Anda.",
                    "properties": {
                      "reference_type": {
                        "type": "string",
                        "enum": [
                          "transaction",
                          "vendor_user",
                          "vendor_business"
                        ],
                        "description": "Objek yang dirujuk oleh `reference_object_uuid`."
                      },
                      "reference_id": {
                        "type": "string",
                        "description": "Pengenal rekaman sumber."
                      }
                    }
                  }
                }
              },
              "examples": {
                "By value": {
                  "value": {
                    "value": "+14155552671",
                    "comment": "Reported fraud"
                  }
                },
                "From a session": {
                  "value": {
                    "reference_session_id": "33333333-4444-5555-6666-777777777777"
                  }
                },
                "Face from a document-capture selfie": {
                  "value": {
                    "reference_session_id": "33333333-4444-5555-6666-777777777777",
                    "face_image_source": "front_image_camera_front"
                  }
                },
                "From a transaction": {
                  "value": {
                    "value": "0x52908400098527886E0F7030069857D2E4169EE7",
                    "reference_object_uuid": "55555555-6666-7777-8888-999999999999",
                    "comment": "Linked to a chargeback",
                    "metadata": {
                      "reference_type": "transaction",
                      "reference_id": "55555555-6666-7777-8888-999999999999"
                    }
                  }
                },
                "Country": {
                  "value": {
                    "value": "PRK",
                    "comment": "Sanctioned jurisdiction"
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://verification.didit.me/v3/lists/11111111-2222-3333-4444-555555555555/entries/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"value\": \"+14155552671\", \"comment\": \"Reported fraud\"}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.lists.entries.create(\n    \"11111111-2222-3333-4444-555555555555\",\n    value=\"+14155552671\",\n    comment=\"Reported fraud\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.lists.entries.create(\"11111111-2222-3333-4444-555555555555\", {\n  value: \"+14155552671\",\n  comment: \"Reported fraud\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Lists.Entries.Create(ctx, \"11111111-2222-3333-4444-555555555555\", didit.ListsEntriesCreateParams{\n\tValue:   didit.String(\"+14155552671\"),\n\tComment: didit.String(\"Reported fraud\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.ListsEntriesCreateParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.lists().entries().create(\"11111111-2222-3333-4444-555555555555\", ListsEntriesCreateParams.builder()\n        .value(\"+14155552671\")\n        .comment(\"Reported fraud\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->lists->entries->create('11111111-2222-3333-4444-555555555555', [\n    'value' => '+14155552671',\n    'comment' => 'Reported fraud',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.lists.entries.create(\n  \"11111111-2222-3333-4444-555555555555\",\n  value: \"+14155552671\",\n  comment: \"Reported fraud\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Lists.Entries.CreateAsync(\"11111111-2222-3333-4444-555555555555\", new ListsEntriesCreateParams\n{\n    Value = \"+14155552671\",\n    Comment = \"Reported fraud\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "201": {
            "description": "Entri berhasil dibuat.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ComplianceListEntry"
                },
                "examples": {
                  "By value": {
                    "value": {
                      "uuid": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee",
                      "value": "+14155552671",
                      "display_label": "",
                      "comment": "Reported fraud",
                      "added_by": "api",
                      "reference_session_id": null,
                      "reference_session_number": null,
                      "reference_session_type": null,
                      "reference_object_uuid": null,
                      "metadata": null,
                      "created_at": "2026-10-12T10:04:51.220391Z"
                    }
                  },
                  "Document from a session": {
                    "value": {
                      "uuid": "bbbbbbbb-cccc-dddd-eeee-ffffffffffff",
                      "value": "X1234567",
                      "display_label": "Jane Doe - X1234567",
                      "comment": "",
                      "added_by": "api",
                      "reference_session_id": "33333333-4444-5555-6666-777777777777",
                      "reference_session_number": 1042,
                      "reference_session_type": "kyc",
                      "reference_object_uuid": "66666666-7777-8888-9999-000000000000",
                      "metadata": {
                        "full_name": "Jane Doe",
                        "issuing_state": "ESP",
                        "document_type": "ID",
                        "region": "",
                        "document_number": "X1234567"
                      },
                      "created_at": "2026-10-12T10:06:12.774915Z"
                    }
                  },
                  "From a transaction": {
                    "value": {
                      "uuid": "dddddddd-eeee-ffff-0000-111111111111",
                      "value": "0x52908400098527886e0f7030069857d2e4169ee7",
                      "display_label": "",
                      "comment": "Linked to a chargeback",
                      "added_by": "api",
                      "reference_session_id": null,
                      "reference_session_number": null,
                      "reference_session_type": null,
                      "reference_object_uuid": "55555555-6666-7777-8888-999999999999",
                      "metadata": {
                        "reference_type": "transaction",
                        "reference_id": "55555555-6666-7777-8888-999999999999"
                      },
                      "created_at": "2026-10-12T10:20:40.117062Z"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Isi permintaan tidak valid, nilai sudah ada dalam daftar, atau sesi tidak dapat menyediakan nilai tersebut.",
            "content": {
              "application/json": {
                "examples": {
                  "Nothing to list": {
                    "value": {
                      "value": [
                        "Either 'value' or 'reference_session_id' must be provided."
                      ]
                    }
                  },
                  "Duplicate value": {
                    "value": {
                      "value": [
                        "An entry with this value already exists in this list."
                      ]
                    }
                  },
                  "Invalid phone": {
                    "value": {
                      "value": [
                        "Invalid phone number. Provide a valid international number (e.g. +1234567890)."
                      ]
                    }
                  },
                  "Invalid IP": {
                    "value": {
                      "value": [
                        "Invalid IP address or CIDR range (e.g. 192.168.1.1 or 10.0.0.0/24)."
                      ]
                    }
                  },
                  "Invalid country": {
                    "value": {
                      "value": [
                        "Invalid country code: XX. Provide a valid ISO 3166-1 alpha-2 or alpha-3 country code."
                      ]
                    }
                  },
                  "Device-class fingerprint": {
                    "value": {
                      "value": [
                        "This value is a device-class fingerprint: several distinct devices have reported it, so blocklisting it would decline unrelated people. Block the user by document, face, email or phone instead."
                      ]
                    }
                  },
                  "Unknown session": {
                    "value": {
                      "reference_session_id": [
                        "Session not found or does not belong to this application."
                      ]
                    }
                  },
                  "No data in session": {
                    "value": {
                      "value": [
                        "Either provide a 'value' or ensure the session contains data for this entry type."
                      ]
                    }
                  },
                  "Selfie on another list": {
                    "value": {
                      "face_image_source": [
                        "A document-capture selfie can only be added to the face blocklist."
                      ]
                    }
                  },
                  "No clear face in selfie": {
                    "value": {
                      "face_image_source": [
                        "No clear face was found in this selfie, so it cannot be blocklisted."
                      ]
                    }
                  },
                  "Selfie already listed": {
                    "value": {
                      "face_image_source": [
                        "This selfie is already in the blocklist."
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Kunci API dengan cakupan terbatas telah kedaluwarsa. Kegagalan autentikasi lainnya mengembalikan `403`.",
            "content": {
              "application/json": {
                "examples": {
                  "Expired API key": {
                    "value": {
                      "detail": "This API key has expired."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Header `x-api-key` tidak ada (kunci yang salah, dicabut, atau kedaluwarsa menghasilkan `401`), atau kunci API dengan cakupan tertentu tidak memiliki `workflows: write` atau digunakan dari alamat IP di luar daftar izinnya.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing or invalid API key": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Scoped key without workflows access": {
                    "value": {
                      "detail": "This API key has no write access to workflows."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Tidak ada daftar dengan UUID ini di aplikasi milik kunci API, atau daftar tersebut telah dihapus.",
            "content": {
              "application/json": {
                "examples": {
                  "Not found": {
                    "value": {
                      "detail": "List not found."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimitedWrite"
          },
          "503": {
            "description": "Analisis wajah untuk swafoto dari pengambilan dokumen tidak tersedia untuk sementara. Tidak ada yang ditambahkan; coba lagi nanti.",
            "content": {
              "application/json": {
                "examples": {
                  "Unavailable": {
                    "value": {
                      "detail": "Service temporarily unavailable. Please try again later."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/lists/{list_uuid}/entries/{entry_uuid}/": {
      "delete": {
        "summary": "Hapus entri daftar",
        "description": "Menghapus satu entri dari sebuah daftar, termasuk daftar sistem. Entri tersebut langsung berhenti cocok, dan penghapusan tidak dapat dibatalkan: untuk mencantumkan nilainya lagi, buat entri baru. Pada daftar blokir sistem untuk wajah, dokumen, telepon, atau email, catatan yang diwakili oleh entri tersebut tidak lagi ditandai sebagai masuk daftar blokir; pada daftar blokir sistem untuk pengguna atau bisnis, pengguna atau bisnis pada aplikasi yang memiliki `vendor_data` sama dengan nilai entri tersebut (atau yang memiliki `didit_internal_id` sama dengan `reference_object_uuid`-nya) dan berstatus `BLOCKED` akan kembali menjadi `ACTIVE`. Sesi dan transaksi yang telah selesai tetap mempertahankan statusnya. Kunci API dengan cakupan membutuhkan `workflows: write`.",
        "operationId": "delete_list_entry",
        "x-didit-sdk": {
          "resource": "lists.entries",
          "method": "delete",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Lists"
        ],
        "parameters": [
          {
            "name": "list_uuid",
            "in": "path",
            "required": true,
            "description": "UUID dari daftar yang memuat entri tersebut.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "11111111-2222-3333-4444-555555555555"
          },
          {
            "name": "entry_uuid",
            "in": "path",
            "required": true,
            "description": "UUID entri, seperti yang dikembalikan oleh Cantumkan entri daftar atau Buat entri daftar.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X DELETE 'https://verification.didit.me/v3/lists/11111111-2222-3333-4444-555555555555/entries/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nclient.lists.entries.delete(\n    \"11111111-2222-3333-4444-555555555555\",\n    \"aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee\",\n)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nawait didit.lists.entries.delete(\n  \"11111111-2222-3333-4444-555555555555\",\n  \"aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee\",\n);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nif err := client.Lists.Entries.Delete(ctx, \"11111111-2222-3333-4444-555555555555\", \"aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee\"); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nclient.lists().entries().delete(\"11111111-2222-3333-4444-555555555555\", \"aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee\");"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$didit->lists->entries->delete('11111111-2222-3333-4444-555555555555', 'aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee');"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.lists.entries.delete(\n  \"11111111-2222-3333-4444-555555555555\",\n  \"aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee\"\n)"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nawait client.Lists.Entries.DeleteAsync(\"11111111-2222-3333-4444-555555555555\", \"aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee\");"
          }
        ],
        "responses": {
          "204": {
            "description": "Entri telah dihapus. Tanpa isi."
          },
          "401": {
            "description": "Kunci API dengan cakupan terbatas telah kedaluwarsa. Kegagalan autentikasi lainnya mengembalikan `403`.",
            "content": {
              "application/json": {
                "examples": {
                  "Expired API key": {
                    "value": {
                      "detail": "This API key has expired."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Header `x-api-key` tidak ada (kunci yang salah, dicabut, atau kedaluwarsa menghasilkan `401`), atau kunci API dengan cakupan tertentu tidak memiliki `workflows: write` atau digunakan dari alamat IP di luar daftar izinnya.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing or invalid API key": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Scoped key without workflows access": {
                    "value": {
                      "detail": "This API key has no write access to workflows."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Tidak ada entri dengan UUID ini di daftar ini, daftar tidak berada di aplikasi milik kunci API atau telah dihapus, atau entri tersebut sudah dihapus.",
            "content": {
              "application/json": {
                "examples": {
                  "Not found": {
                    "value": {
                      "detail": "No ListEntry matches the given query."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimitedWrite"
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/lists/{list_uuid}/entries/face-upload/": {
      "post": {
        "summary": "Unggah wajah ke daftar",
        "description": "Menambahkan wajah ke daftar blokir wajah atau daftar izin wajah dari gambar JPEG atau PNG berenkode base64, ketika Anda tidak memiliki sesi verifikasi untuk dijadikan referensi. Didit mendeteksi wajah dalam gambar, menggunakan wajah terbesar, dan membuat entri yang nilai `value` dan `reference_object_uuid`-nya adalah UUID wajah baru tersebut. Wajah yang masuk daftar blokir menolak sesi baru yang wajahnya cocok; wajah yang masuk daftar izin melewati tindakan duplikasi wajah dan tidak pernah mengesampingkan kecocokan daftar blokir. Dalam aplikasi sandbox, gambar tidak dianalisis dan entri tersebut tidak mencocokkan apa pun. Kunci API dengan cakupan memerlukan `workflows: write`. Untuk mendaftarkan wajah dari sesi yang ada, gunakan [Buat entri daftar](https://docs.didit.me/id/management-api/lists/create-entry) dengan `reference_session_id` sebagai gantinya.",
        "operationId": "upload_list_entry_face",
        "x-didit-sdk": {
          "resource": "lists.entries",
          "method": "upload_face",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Lists"
        ],
        "parameters": [
          {
            "name": "list_uuid",
            "in": "path",
            "required": true,
            "description": "UUID dari daftar dengan `entry_type: face` dan `list_type: blocklist` atau `allowlist`.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "11111111-2222-3333-4444-555555555555"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "image"
                ],
                "properties": {
                  "image": {
                    "type": "string",
                    "format": "byte",
                    "description": "JPEG atau PNG yang di-encode Base64, maksimal 2 MB setelah didecode, menampilkan wajah yang terlihat jelas. Kirim string base64 mentah, tanpa awalan `data:image/...;base64,`."
                  },
                  "comment": {
                    "type": "string",
                    "default": "",
                    "description": "Catatan teks bebas opsional, seperti alasan pencantuman."
                  }
                }
              },
              "examples": {
                "Face image": {
                  "value": {
                    "image": "/9j/4AAQSkZJRgABAQAAAQABAAD...",
                    "comment": "Known fraud attempt"
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://verification.didit.me/v3/lists/11111111-2222-3333-4444-555555555555/entries/face-upload/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d \"{\\\"image\\\": \\\"$(base64 < face.jpg | tr -d '\\n')\\\", \\\"comment\\\": \\\"Known fraud attempt\\\"}\""
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.lists.entries.upload_face(\n    \"11111111-2222-3333-4444-555555555555\",\n    image=\"/9j/4AAQSkZJRgABAQAAAQABAAD...\",\n    comment=\"Known fraud attempt\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.lists.entries.uploadFace(\"11111111-2222-3333-4444-555555555555\", {\n  image: \"/9j/4AAQSkZJRgABAQAAAQABAAD...\",\n  comment: \"Known fraud attempt\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Lists.Entries.UploadFace(ctx, \"11111111-2222-3333-4444-555555555555\", didit.ListsEntriesUploadFaceParams{\n\tImage:   \"/9j/4AAQSkZJRgABAQAAAQABAAD...\",\n\tComment: didit.String(\"Known fraud attempt\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.ListsEntriesUploadFaceParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.lists().entries().uploadFace(\"11111111-2222-3333-4444-555555555555\", ListsEntriesUploadFaceParams.builder()\n        .image(\"/9j/4AAQSkZJRgABAQAAAQABAAD...\")\n        .comment(\"Known fraud attempt\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->lists->entries->uploadFace('11111111-2222-3333-4444-555555555555', [\n    'image' => '/9j/4AAQSkZJRgABAQAAAQABAAD...',\n    'comment' => 'Known fraud attempt',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.lists.entries.upload_face(\n  \"11111111-2222-3333-4444-555555555555\",\n  image: \"/9j/4AAQSkZJRgABAQAAAQABAAD...\",\n  comment: \"Known fraud attempt\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Lists.Entries.UploadFaceAsync(\"11111111-2222-3333-4444-555555555555\", new ListsEntriesUploadFaceParams\n{\n    Image = \"/9j/4AAQSkZJRgABAQAAAQABAAD...\",\n    Comment = \"Known fraud attempt\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "201": {
            "description": "Entri wajah telah dibuat.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ComplianceListEntry"
                },
                "examples": {
                  "Uploaded face": {
                    "value": {
                      "uuid": "cccccccc-dddd-eeee-ffff-000000000000",
                      "value": "44444444-5555-6666-7777-888888888888",
                      "display_label": "Manually uploaded face",
                      "comment": "Known fraud attempt",
                      "added_by": "api",
                      "reference_session_id": null,
                      "reference_session_number": null,
                      "reference_session_type": null,
                      "reference_object_uuid": "44444444-5555-6666-7777-888888888888",
                      "metadata": {
                        "reference_image_url": "https://media.example.com/faces/reference.jpg?expires=1760263938&signature=3f9a1c"
                      },
                      "created_at": "2026-10-12T10:12:18.904467Z"
                    }
                  },
                  "Sandbox application": {
                    "value": {
                      "uuid": "cccccccc-dddd-eeee-ffff-000000000000",
                      "value": "44444444-5555-6666-7777-888888888888",
                      "display_label": "Sandbox face entry",
                      "comment": "Known fraud attempt",
                      "added_by": "api",
                      "reference_session_id": null,
                      "reference_session_number": null,
                      "reference_session_type": null,
                      "reference_object_uuid": "44444444-5555-6666-7777-888888888888",
                      "metadata": {
                        "sandbox": true
                      },
                      "created_at": "2026-10-12T10:12:18.904467Z"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Daftar tidak menerima unggahan wajah, atau gambar tidak ada, tidak valid, terlalu besar, atau tidak menampilkan wajah yang dapat digunakan. Tidak ada entri yang dibuat.",
            "content": {
              "application/json": {
                "examples": {
                  "Not a face list": {
                    "value": {
                      "detail": "Face upload is only available for face-type lists."
                    }
                  },
                  "Custom face list": {
                    "value": {
                      "detail": "Face upload is only available for face blocklists and allowlists."
                    }
                  },
                  "Missing image": {
                    "value": {
                      "image": [
                        "This field is required."
                      ]
                    }
                  },
                  "Invalid base64": {
                    "value": {
                      "image": [
                        "Invalid base64 encoding."
                      ]
                    }
                  },
                  "Too large": {
                    "value": {
                      "image": [
                        "Image exceeds maximum size of 2 MB."
                      ]
                    }
                  },
                  "Unreadable image": {
                    "value": {
                      "image": "Invalid image. Provide a valid base64-encoded JPG or PNG."
                    }
                  },
                  "No face": {
                    "value": {
                      "image": "No face detected in the image. Please upload a clear photo with a visible face."
                    }
                  },
                  "No usable face": {
                    "value": {
                      "image": "Could not extract face embedding. Try a different image."
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Kunci API dengan cakupan terbatas telah kedaluwarsa. Kegagalan autentikasi lainnya mengembalikan `403`.",
            "content": {
              "application/json": {
                "examples": {
                  "Expired API key": {
                    "value": {
                      "detail": "This API key has expired."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Header `x-api-key` tidak ada (kunci yang salah, dicabut, atau kedaluwarsa menghasilkan `401`), atau kunci API dengan cakupan tertentu tidak memiliki `workflows: write` atau digunakan dari alamat IP di luar daftar izinnya.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing or invalid API key": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Scoped key without workflows access": {
                    "value": {
                      "detail": "This API key has no write access to workflows."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Tidak ada daftar dengan UUID ini di aplikasi milik kunci API, atau daftar tersebut telah dihapus.",
            "content": {
              "application/json": {
                "examples": {
                  "Not found": {
                    "value": {
                      "detail": "List not found."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimitedWrite"
          },
          "503": {
            "description": "Analisis wajah tidak tersedia untuk sementara. Tidak ada entri yang dibuat; coba lagi nanti.",
            "content": {
              "application/json": {
                "examples": {
                  "Unavailable": {
                    "value": {
                      "detail": "Service temporarily unavailable. Please try again later."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/blocklist/": {
      "get": {
        "summary": "Daftar item yang masuk daftar blokir",
        "description": "Mengembalikan satu feed terpaginasi dari wajah, dokumen identitas, nomor telepon, dan alamat email dari sesi verifikasi aplikasi yang saat ini masuk daftar blokir, `blocklisted_at` terbaru terlebih dahulu; filter dengan `item_type`. Item dari sesi yang dihapus tidak disertakan. Feed ini mencakup catatan yang dimasukkan ke daftar blokir dari suatu sesi (dengan [Tambahkan item sesi ke daftar blokir](https://docs.didit.me/id/management-api/blocklist/add), dari konsol, atau oleh entri daftar yang dibuat dari suatu sesi); nilai yang ditambahkan ke daftar secara manual, wajah yang diunggah, wajah dari swafoto pengambilan dokumen, dan jenis entri lainnya dibaca dengan [Daftar entri daftar](https://docs.didit.me/id/management-api/lists/list-entries). `face_image` dan `front_image` adalah URL bertanda tangan berumur pendek, dan kunci API ber-scope tanpa `media: read` menerima `null`. Kunci API ber-scope memerlukan `workflows: read`.",
        "operationId": "list_blocklist_items",
        "x-didit-sdk": {
          "resource": "blocklist",
          "method": "list",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Blocklist"
        ],
        "parameters": [
          {
            "name": "item_type",
            "in": "query",
            "required": false,
            "description": "Hanya item dari jenis ini. Jika dihilangkan, semua jenis dikembalikan.",
            "schema": {
              "type": "string",
              "enum": [
                "face",
                "document",
                "phone",
                "email"
              ]
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Ukuran halaman. Nilai default-nya 50. Nilai di atas 1000000 mengembalikan `400`; nol, nilai negatif, atau nilai non-numerik akan kembali ke 50.",
            "schema": {
              "type": "integer",
              "default": 50,
              "minimum": 1,
              "maximum": 1000000
            }
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "description": "Indeks berbasis nol dari item pertama yang dikembalikan. Sebaiknya ikuti `next`. Nilai di atas 1000000 mengembalikan `400`; nilai negatif atau non-numerik akan kembali ke 0.",
            "schema": {
              "type": "integer",
              "default": 0,
              "minimum": 0,
              "maximum": 1000000
            }
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/blocklist/?item_type=document' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nfor item in client.blocklist.list():\n    print(item)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nfor await (const item of didit.blocklist.list()) {\n  console.log(item);\n}"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\niter := client.Blocklist.ListAutoPaging(ctx, didit.BlocklistListParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nfor (var item : client.blocklist().list()) {\n    System.out.println(item);\n}"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\nforeach ($didit->blocklist->list() as $item) {\n    print_r($item->toArray());\n}"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.blocklist.list.auto_paging_each do |item|\n  puts item.to_h\nend"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.Blocklist.ListAsync())\n{\n    Console.WriteLine(JsonSerializer.Serialize(item));\n}"
          }
        ],
        "responses": {
          "200": {
            "description": "Satu halaman item daftar blokir, yang terbaru lebih dulu.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "count",
                    "next",
                    "previous",
                    "results"
                  ],
                  "properties": {
                    "count": {
                      "type": "integer",
                      "minimum": 0,
                      "description": "Jumlah total item dalam daftar blokir yang cocok dengan filter."
                    },
                    "next": {
                      "type": "string",
                      "format": "uri",
                      "nullable": true,
                      "description": "URL absolut halaman berikutnya, atau `null` di halaman terakhir."
                    },
                    "previous": {
                      "type": "string",
                      "format": "uri",
                      "nullable": true,
                      "description": "URL absolut halaman sebelumnya, atau `null` di halaman pertama."
                    },
                    "results": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/BlocklistedItem"
                      }
                    }
                  }
                },
                "examples": {
                  "Mixed feed": {
                    "value": {
                      "count": 2,
                      "next": null,
                      "previous": null,
                      "results": [
                        {
                          "type": "document",
                          "session_id": "33333333-4444-5555-6666-777777777777",
                          "session_number": 1042,
                          "blocklisted_at": "2026-10-12T10:06:12.701553Z",
                          "face_image": null,
                          "document_type": "ID",
                          "document_number": "X1234567",
                          "front_image": "https://media.example.com/documents/front.jpg?expires=1760263938&signature=8b2e47",
                          "phone_number": null,
                          "country_code": null,
                          "email": null
                        },
                        {
                          "type": "phone",
                          "session_id": "77777777-8888-9999-0000-111111111111",
                          "session_number": 1017,
                          "blocklisted_at": "2026-10-08T15:31:09.400127Z",
                          "face_image": null,
                          "document_type": null,
                          "document_number": null,
                          "front_image": null,
                          "phone_number": "+14155552671",
                          "country_code": "US",
                          "email": null
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Parameter kueri tidak valid.",
            "content": {
              "application/json": {
                "examples": {
                  "Unknown item type": {
                    "value": {
                      "item_type": [
                        "\"wallet\" is not a valid choice."
                      ]
                    }
                  },
                  "Limit too large": {
                    "value": [
                      "limit must not exceed 1000000."
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Kunci API dengan cakupan terbatas telah kedaluwarsa. Kegagalan autentikasi lainnya mengembalikan `403`.",
            "content": {
              "application/json": {
                "examples": {
                  "Expired API key": {
                    "value": {
                      "detail": "This API key has expired."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Header `x-api-key` tidak ada (kunci yang salah, dicabut, atau kedaluwarsa menghasilkan `401`), atau kunci API dengan cakupan tertentu tidak memiliki `workflows: read` atau digunakan dari alamat IP di luar daftar izinnya.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing or invalid API key": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Scoped key without workflows access": {
                    "value": {
                      "detail": "This API key has no read access to workflows."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Batas baca bersama sebesar 600 permintaan per menit per kunci API telah terlampaui. Patuhi `Retry-After` sebelum mencoba lagi.",
            "content": {
              "application/json": {
                "examples": {
                  "Rate limited": {
                    "value": {
                      "detail": "GET request rate limit exceeded. You can make up to 600 requests per minute."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/blocklist/add/": {
      "post": {
        "summary": "Tambahkan item sesi ke daftar blokir",
        "description": "Memasukkan wajah, dokumen identitas, nomor telepon, atau alamat email dari satu sesi verifikasi individu pada aplikasi ke daftar blokir. Untuk setiap jenis yang dipilih, Didit mengambil rekaman terbaru sesi tersebut, menandainya sebagai masuk daftar blokir, dan menambahkan entri yang ditautkan ke sesi tersebut ke daftar blokir sistem yang cocok (`added_by: \"api\"`), sehingga sesi baru dengan wajah, nomor dokumen, nomor telepon, atau alamat email yang cocok akan ditolak. Setiap item yang dipilih diperiksa terlebih dahulu, jadi jika salah satu hilang, tidak ada yang dimasukkan ke daftar blokir; mengulang panggilan untuk item yang sudah terdaftar akan mempertahankan entri tunggalnya dan memperbarui `blocklisted_at`. Sesi itu sendiri dan sesi yang sudah selesai tidak diubah. Kunci API dengan pembatasan izin memerlukan `workflows: write`.",
        "operationId": "add_to_blocklist",
        "x-didit-sdk": {
          "resource": "blocklist",
          "method": "add",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Blocklist"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "session_id"
                ],
                "description": "Setidaknya satu flag `blocklist_*` harus bernilai `true`.",
                "properties": {
                  "session_id": {
                    "type": "string",
                    "format": "uuid",
                    "description": "Sesi verifikasi perorangan dari aplikasi Anda. Sesi yang telah dihapus akan ditolak."
                  },
                  "blocklist_face": {
                    "type": "boolean",
                    "default": false,
                    "description": "Masukkan wajah sesi ke daftar blokir."
                  },
                  "blocklist_document": {
                    "type": "boolean",
                    "default": false,
                    "description": "Masukkan dokumen identitas sesi ke daftar blokir. Dokumen memerlukan negara bagian penerbit, jenis dokumen, nomor dokumen, dan nama lengkap."
                  },
                  "blocklist_phone": {
                    "type": "boolean",
                    "default": false,
                    "description": "Masukkan nomor telepon sesi ke daftar blokir."
                  },
                  "blocklist_email": {
                    "type": "boolean",
                    "default": false,
                    "description": "Masukkan alamat email sesi ke daftar blokir."
                  }
                }
              },
              "examples": {
                "Face and document": {
                  "value": {
                    "session_id": "33333333-4444-5555-6666-777777777777",
                    "blocklist_face": true,
                    "blocklist_document": true
                  }
                },
                "Phone only": {
                  "value": {
                    "session_id": "33333333-4444-5555-6666-777777777777",
                    "blocklist_phone": true
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://verification.didit.me/v3/blocklist/add/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"session_id\": \"33333333-4444-5555-6666-777777777777\",\n    \"blocklist_face\": true,\n    \"blocklist_document\": true\n  }'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.blocklist.add(\n    session_id=\"33333333-4444-5555-6666-777777777777\",\n    blocklist_face=True,\n    blocklist_document=True,\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.blocklist.add({\n  session_id: \"33333333-4444-5555-6666-777777777777\",\n  blocklist_face: true,\n  blocklist_document: true,\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Blocklist.Add(ctx, didit.BlocklistAddParams{\n\tSessionID:         \"33333333-4444-5555-6666-777777777777\",\n\tBlocklistFace:     didit.Bool(true),\n\tBlocklistDocument: didit.Bool(true),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.BlocklistAddParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.blocklist().add(BlocklistAddParams.builder()\n        .sessionId(\"33333333-4444-5555-6666-777777777777\")\n        .blocklistFace(true)\n        .blocklistDocument(true)\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->blocklist->add([\n    'session_id' => '33333333-4444-5555-6666-777777777777',\n    'blocklist_face' => true,\n    'blocklist_document' => true,\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.blocklist.add(\n  session_id: \"33333333-4444-5555-6666-777777777777\",\n  blocklist_face: true,\n  blocklist_document: true\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Blocklist.AddAsync(new BlocklistAddParams\n{\n    SessionId = \"33333333-4444-5555-6666-777777777777\",\n    BlocklistFace = true,\n    BlocklistDocument = true,\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "Item yang dipilih dimasukkan ke daftar blokir.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "message"
                  ],
                  "properties": {
                    "message": {
                      "type": "string",
                      "description": "Selalu `Successfully updated blocklist.`"
                    }
                  }
                },
                "examples": {
                  "Blocklisted": {
                    "value": {
                      "message": "Successfully updated blocklist."
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Isi permintaan tidak valid, sesi bukan sesi verifikasi dari aplikasi ini, atau tidak memiliki catatan dari tipe yang dipilih. Tidak ada yang dimasukkan ke daftar blokir.",
            "content": {
              "application/json": {
                "examples": {
                  "Unknown session": {
                    "value": {
                      "non_field_errors": [
                        "Session not found"
                      ]
                    }
                  },
                  "No item selected": {
                    "value": {
                      "non_field_errors": [
                        "Must specify at least one item to blocklist"
                      ]
                    }
                  },
                  "No face record": {
                    "value": {
                      "non_field_errors": [
                        "Session does not have a face record"
                      ]
                    }
                  },
                  "Incomplete document": {
                    "value": {
                      "non_field_errors": [
                        "To blocklist a document, the document must have an issuing state, document type, document number and full name"
                      ]
                    }
                  },
                  "Invalid session id": {
                    "value": {
                      "session_id": [
                        "Must be a valid UUID."
                      ]
                    }
                  },
                  "Missing session id": {
                    "value": {
                      "session_id": [
                        "This field is required."
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Kunci API dengan cakupan terbatas telah kedaluwarsa. Kegagalan autentikasi lainnya mengembalikan `403`.",
            "content": {
              "application/json": {
                "examples": {
                  "Expired API key": {
                    "value": {
                      "detail": "This API key has expired."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Header `x-api-key` tidak ada (kunci yang salah, dicabut, atau kedaluwarsa menghasilkan `401`), atau kunci API dengan cakupan tertentu tidak memiliki `workflows: write` atau digunakan dari alamat IP di luar daftar izinnya.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing or invalid API key": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Scoped key without workflows access": {
                    "value": {
                      "detail": "This API key has no write access to workflows."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimitedWrite"
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/blocklist/remove/": {
      "post": {
        "summary": "Hapus item sesi dari daftar blokir",
        "description": "Membuka pemblokiran pada wajah, dokumen identitas, nomor telepon, atau alamat email dari satu sesi verifikasi individu aplikasi. Untuk setiap jenis yang dipilih, Didit mengambil rekaman terbaru sesi tersebut, menghapus tanda daftar blokirnya, dan menghapus entri daftar blokir sistem yang dibuat dari rekaman tersebut, sehingga tidak lagi menolak sesi baru. Entri yang ditambahkan ke daftar berdasarkan nilai tidak akan diubah: temukan entri tersebut dengan [List list entries](https://docs.didit.me/id/management-api/lists/list-entries) dan hapus dengan [Delete a list entry](https://docs.didit.me/id/management-api/lists/delete-entry). Membuka pemblokiran rekaman yang tidak masuk daftar blokir akan berhasil dan tidak mengubah apa pun, serta sesi yang sudah selesai tidak akan diubah. Kunci API dengan pembatasan cakupan memerlukan `workflows: write`.",
        "operationId": "remove_from_blocklist",
        "x-didit-sdk": {
          "resource": "blocklist",
          "method": "remove",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Blocklist"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "session_id"
                ],
                "description": "Setidaknya satu flag `unblock_*` harus bernilai `true`.",
                "properties": {
                  "session_id": {
                    "type": "string",
                    "format": "uuid",
                    "description": "Sesi verifikasi perorangan dari aplikasi Anda. Sesi yang telah dihapus akan ditolak."
                  },
                  "unblock_face": {
                    "type": "boolean",
                    "default": false,
                    "description": "Buka pemblokiran pada wajah sesi."
                  },
                  "unblock_document": {
                    "type": "boolean",
                    "default": false,
                    "description": "Buka pemblokiran pada dokumen identitas sesi."
                  },
                  "unblock_phone": {
                    "type": "boolean",
                    "default": false,
                    "description": "Buka pemblokiran pada nomor telepon sesi."
                  },
                  "unblock_email": {
                    "type": "boolean",
                    "default": false,
                    "description": "Buka pemblokiran pada alamat email sesi."
                  }
                }
              },
              "examples": {
                "Face and document": {
                  "value": {
                    "session_id": "33333333-4444-5555-6666-777777777777",
                    "unblock_face": true,
                    "unblock_document": true
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://verification.didit.me/v3/blocklist/remove/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"session_id\": \"33333333-4444-5555-6666-777777777777\",\n    \"unblock_face\": true,\n    \"unblock_document\": true\n  }'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.blocklist.remove(\n    session_id=\"33333333-4444-5555-6666-777777777777\",\n    unblock_face=True,\n    unblock_document=True,\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.blocklist.remove({\n  session_id: \"33333333-4444-5555-6666-777777777777\",\n  unblock_face: true,\n  unblock_document: true,\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Blocklist.Remove(ctx, didit.BlocklistRemoveParams{\n\tSessionID:       \"33333333-4444-5555-6666-777777777777\",\n\tUnblockFace:     didit.Bool(true),\n\tUnblockDocument: didit.Bool(true),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.BlocklistRemoveParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.blocklist().remove(BlocklistRemoveParams.builder()\n        .sessionId(\"33333333-4444-5555-6666-777777777777\")\n        .unblockFace(true)\n        .unblockDocument(true)\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->blocklist->remove([\n    'session_id' => '33333333-4444-5555-6666-777777777777',\n    'unblock_face' => true,\n    'unblock_document' => true,\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.blocklist.remove(\n  session_id: \"33333333-4444-5555-6666-777777777777\",\n  unblock_face: true,\n  unblock_document: true\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Blocklist.RemoveAsync(new BlocklistRemoveParams\n{\n    SessionId = \"33333333-4444-5555-6666-777777777777\",\n    UnblockFace = true,\n    UnblockDocument = true,\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "Pemblokiran pada item yang dipilih telah dicabut.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "message"
                  ],
                  "properties": {
                    "message": {
                      "type": "string",
                      "description": "Selalu `Successfully removed from blocklist.`"
                    }
                  }
                },
                "examples": {
                  "Unblocked": {
                    "value": {
                      "message": "Successfully removed from blocklist."
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Isi permintaan tidak valid, sesi bukan sesi verifikasi dari aplikasi ini, atau tidak memiliki catatan dari tipe yang dipilih. Tidak ada yang diubah.",
            "content": {
              "application/json": {
                "examples": {
                  "Unknown session": {
                    "value": {
                      "non_field_errors": [
                        "Session not found"
                      ]
                    }
                  },
                  "No item selected": {
                    "value": {
                      "non_field_errors": [
                        "Must specify at least one item to unblock"
                      ]
                    }
                  },
                  "No email record": {
                    "value": {
                      "non_field_errors": [
                        "Session does not have an email record"
                      ]
                    }
                  },
                  "Invalid session id": {
                    "value": {
                      "session_id": [
                        "Must be a valid UUID."
                      ]
                    }
                  },
                  "Missing session id": {
                    "value": {
                      "session_id": [
                        "This field is required."
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Kunci API dengan cakupan terbatas telah kedaluwarsa. Kegagalan autentikasi lainnya mengembalikan `403`.",
            "content": {
              "application/json": {
                "examples": {
                  "Expired API key": {
                    "value": {
                      "detail": "This API key has expired."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Header `x-api-key` tidak ada (kunci yang salah, dicabut, atau kedaluwarsa menghasilkan `401`), atau kunci API dengan cakupan tertentu tidak memiliki `workflows: write` atau digunakan dari alamat IP di luar daftar izinnya.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing or invalid API key": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Scoped key without workflows access": {
                    "value": {
                      "detail": "This API key has no write access to workflows."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimitedWrite"
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/webhook/": {
      "get": {
        "summary": "Dapatkan konfigurasi webhook",
        "description": "Mengembalikan pengaturan webhook aplikasi dalam satu panggilan: setiap [tujuan webhook](https://docs.didit.me/id/management-api/webhook/list-destinations) beserta rahasia penandatanganannya, jenis event yang dapat dilanggani oleh tujuan tersebut, URL, versi, dan rahasia webhook tingkat aplikasi (lama), kebijakan retensi data dan templat biometrik, serta host pengembalian dompet Digital ID. Didit mengirimkan webhook ke tujuan, masing-masing ditandatangani dengan `secret_shared_key` miliknya sendiri; `webhook_url`, `webhook_version`, dan `secret_shared_key` tingkat atas hanya digunakan saat tidak ada tujuan yang diaktifkan, dan itu pun hanya untuk `status.updated` dan `data.updated`. Respons ini memuat rahasia penandatanganan, jadi jauhkan dari log dan kode sisi klien. Kunci API dengan cakupan memerlukan `webhooks: read`.",
        "operationId": "get_webhook_config",
        "x-didit-sdk": {
          "resource": "webhooks",
          "method": "retrieve_config",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Webhook"
        ],
        "parameters": [],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/webhook/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.webhooks.retrieve_config()\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.webhooks.retrieveConfig();\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Webhooks.RetrieveConfig(ctx)\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.webhooks().retrieveConfig();\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->webhooks->retrieveConfig();\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.webhooks.retrieve_config\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Webhooks.RetrieveConfigAsync();\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "Konfigurasi webhook.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookConfig"
                },
                "examples": {
                  "One destination": {
                    "value": {
                      "webhook_url": "https://yourapp.com/webhooks/didit",
                      "webhook_version": "v3",
                      "secret_shared_key": "dGhpcy1pcy10aGUtYXBwLWxldmVsLXNlY3JldC0wMDA",
                      "capture_method": "MOBILE",
                      "data_retention_months": 24,
                      "face_retention_policy": "delete_with_session",
                      "face_retention_days": null,
                      "biometric_consent_mode": "auto",
                      "available_events": [
                        {
                          "value": "status.updated",
                          "label": "Session status updated"
                        },
                        {
                          "value": "data.updated",
                          "label": "Session data updated"
                        },
                        {
                          "value": "user.status.updated",
                          "label": "User status updated"
                        },
                        {
                          "value": "user.data.updated",
                          "label": "User data updated"
                        },
                        {
                          "value": "business.status.updated",
                          "label": "Business status updated"
                        },
                        {
                          "value": "business.data.updated",
                          "label": "Business data updated"
                        },
                        {
                          "value": "activity.created",
                          "label": "Activity created"
                        },
                        {
                          "value": "transaction.created",
                          "label": "Transaction created"
                        },
                        {
                          "value": "transaction.status.updated",
                          "label": "Transaction status updated"
                        },
                        {
                          "value": "travel_rule.status.updated",
                          "label": "Travel Rule Status Updated"
                        },
                        {
                          "value": "workflow.compliance_changed",
                          "label": "Workflow Compliance Changed"
                        }
                      ],
                      "allowed_return_hosts": [
                        "shop.example.com"
                      ],
                      "endpoints": [
                        {
                          "uuid": "11111111-2222-3333-4444-555555555555",
                          "label": "Production session webhooks",
                          "url": "https://yourapp.com/webhooks/didit",
                          "enabled": true,
                          "webhook_version": "v3",
                          "secret_shared_key": "dGhpcy1pcy1hbi1leGFtcGxlLXNlY3JldC0wMDAwMDA",
                          "subscribed_events": [
                            "status.updated",
                            "data.updated"
                          ],
                          "created_at": "2026-01-04T08:00:00.000000Z",
                          "updated_at": "2026-04-22T14:09:11.523671Z"
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Kunci API telah kedaluwarsa: kunci ini dibuat dengan tanggal kedaluwarsa yang telah lewat. Kunci yang salah atau dicabut juga menghasilkan `401`; kunci yang tidak ada menghasilkan `403`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "Pesan kesalahan yang mudah dibaca manusia."
                    }
                  }
                },
                "examples": {
                  "Expired key": {
                    "value": {
                      "detail": "This API key has expired."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Permintaan tidak diizinkan. `x-api-key` yang hilang, tidak valid, atau dicabut akan menghasilkan `You do not have permission to perform this action.` Kunci dengan cakupan terbatas tanpa akses yang dibutuhkan endpoint ini akan menghasilkan pesan yang menyebutkan akses yang hilang, dan kunci yang digunakan dari luar daftar izin IP-nya akan menghasilkan `This API key can't be used from this IP address.`",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "Pesan kesalahan yang mudah dibaca manusia."
                    }
                  }
                },
                "examples": {
                  "Missing or invalid key": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Scoped key without webhooks read": {
                    "value": {
                      "detail": "This API key has no read access to webhooks."
                    }
                  },
                  "Outside the IP allowlist": {
                    "value": {
                      "detail": "This API key can't be used from this IP address."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Batas laju terlampaui: lebih dari 600 permintaan GET dalam jendela satu menit saat ini untuk kunci API ini. Tunggu `Retry-After` detik sebelum mencoba lagi.",
            "headers": {
              "Retry-After": {
                "description": "Detik untuk menunggu sebelum mencoba lagi.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "example": 30
                }
              },
              "X-RateLimit-Limit": {
                "description": "Permintaan yang diizinkan dalam jendela satu menit (600).",
                "schema": {
                  "type": "integer",
                  "example": 600
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Permintaan tersisa dalam jendela saat ini.",
                "schema": {
                  "type": "integer",
                  "example": 0
                }
              },
              "X-RateLimit-Reset": {
                "description": "Waktu Unix (detik) saat jendela saat ini direset.",
                "schema": {
                  "type": "integer",
                  "example": 1792056120
                }
              },
              "X-RateLimit-Scope": {
                "description": "Nama anggaran yang terlampaui.",
                "schema": {
                  "type": "string",
                  "example": "generic-get"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "Pesan kesalahan yang mudah dibaca manusia."
                    }
                  }
                },
                "examples": {
                  "Throttled": {
                    "value": {
                      "detail": "GET request rate limit exceeded. You can make up to 600 requests per minute."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      },
      "patch": {
        "summary": "Perbarui konfigurasi webhook",
        "description": "Perbarui pengaturan tingkat aplikasi secara parsial: URL, versi, dan rahasia webhook lawas, kebijakan retensi data dan templat biometrik, serta host pengembalian dompet Digital ID. Kirim hanya kolom yang ingin diubah; respons berupa konfigurasi lengkap dengan bentuk yang sama seperti `GET /v3/webhook/`. Tujuan tidak dikelola di sini: buat, perbarui, dan hapus tujuan melalui endpoint `/v3/webhook/destinations/`, dan jangan kirim kolom `endpoints` ke endpoint ini. Perubahan `data_retention_months` juga berlaku untuk sesi yang sudah ada, dan sesi yang dihapus tidak dapat dipulihkan; baca [Retensi data](https://docs.didit.me/id/console/data-retention) terlebih dahulu. Kunci API dengan pembatasan cakupan memerlukan `webhooks: write`.",
        "operationId": "update_webhook_config",
        "x-didit-sdk": {
          "resource": "webhooks",
          "method": "update_config",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Webhook"
        ],
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "description": "Kirim hanya kolom yang akan diubah. Tujuan tidak dikelola di sini.",
                "properties": {
                  "webhook_url": {
                    "type": "string",
                    "format": "uri",
                    "nullable": true,
                    "maxLength": 2000,
                    "description": "URL webhook tingkat aplikasi lama. Didit menggunakannya hanya saat aplikasi tidak memiliki tujuan yang aktif, dan kemudian hanya untuk `status.updated` dan `data.updated`. Ini tidak membuat tujuan, dan pembuatan, pembaruan, atau penghapusan tujuan berikutnya akan menggantikannya. Untuk menerima webhook, buat tujuan dengan `POST /v3/webhook/destinations/` sebagai gantinya."
                  },
                  "webhook_version": {
                    "type": "string",
                    "enum": [
                      "v1",
                      "v2",
                      "v3"
                    ],
                    "description": "Versi payload dari `webhook_url` lama."
                  },
                  "rotate_secret_key": {
                    "type": "boolean",
                    "default": false,
                    "description": "`true` mengganti `secret_shared_key` tingkat aplikasi dengan nilai acak baru secara langsung; nilai baru disertakan dalam respons. Rahasia tujuan tidak diubah. Setiap panggilan dengan `true` menghasilkan rahasia baru, sehingga tidak bersifat idempoten."
                  },
                  "capture_method": {
                    "type": "string",
                    "enum": [
                      "MOBILE",
                      "MOBILE_AND_DESKTOP"
                    ],
                    "description": "Pengaturan aplikasi lama. Alur verifikasi tidak membacanya."
                  },
                  "data_retention_months": {
                    "type": "integer",
                    "nullable": true,
                    "minimum": 1,
                    "maximum": 120,
                    "description": "Jendela penghapusan otomatis dalam bulan (satu bulan dihitung sebagai 30 hari), atau `null` untuk tanpa penghapusan otomatis. Perubahan juga berlaku untuk sesi yang ada: setiap sesi verifikasi pengguna yang lebih lama dari jendela baru akan dihapus secara otomatis, dan penghapusan tersebut tidak dapat dibatalkan."
                  },
                  "face_retention_policy": {
                    "type": "string",
                    "enum": [
                      "delete_with_session",
                      "retain_until_user_deleted"
                    ],
                    "description": "Hal yang terjadi pada embedding wajah sesi saat sesi dihapus. `retain_until_user_deleted` memerlukan `face_retention_days` dalam permintaan yang sama atau yang sudah diatur sebelumnya. Perubahan berlaku untuk penghapusan sesi setelahnya; perubahan ini tidak membuat atau menghapus secara permanen templat biometrik yang sudah ada."
                  },
                  "face_retention_days": {
                    "type": "integer",
                    "nullable": true,
                    "minimum": 1,
                    "maximum": 3650,
                    "description": "Periode retensi data, dalam hari, untuk templat biometrik di bawah `retain_until_user_deleted`."
                  },
                  "biometric_consent_mode": {
                    "type": "string",
                    "enum": [
                      "auto",
                      "always",
                      "never"
                    ],
                    "description": "Kapan alur yang di-hosting dan SDK native meminta persetujuan biometrik eksplisit dari pengguna sebelum pengambilan wajah. `auto` (default) hanya meminta jika pemicu berlaku: negara bagian yang dinyatakan, IP pengguna, atau penerbit dokumen identitas berada di Illinois, Texas, atau Colorado, atau pengguna tampaknya berada di AS tanpa negara bagian yang diketahui. `always` meminta kepada setiap pengguna yang alur kerjanya mengambil gambar wajah. `never` tidak pernah menampilkan langkah tersebut, dan Anda mengumpulkan persetujuan sendiri sebelum swafoto. Setiap perubahan dicatat dalam log audit. Lihat [Persetujuan biometrik](https://docs.didit.me/id/getting-started/biometric-consent)."
                  },
                  "allowed_return_hosts": {
                    "type": "array",
                    "maxItems": 20,
                    "description": "Mengganti seluruh daftar host pengembalian dompet ID Digital. Hanya hostname murni, seperti `shop.example.com`: tanpa skema, port, path, atau wildcard. Nilai diubah menjadi huruf kecil dan duplikat dihapus. Kirim `[]` untuk mengosongkan daftar.",
                    "items": {
                      "type": "string",
                      "maxLength": 253
                    }
                  },
                  "allowed_domains": {
                    "type": "array",
                    "maxItems": 50,
                    "items": {
                      "type": "string",
                      "maxLength": 300
                    },
                    "description": "Mengganti seluruh daftar origin yang diizinkan. Origin (misalnya `https://app.example.com`; `http` hanya untuk `localhost`) tempat alur verifikasi yang di-hosting dapat disematkan dan dapat mengarahkan pengguna kembali dengan callback sesi. Panggilan server-ke-server tidak terpengaruh. Daftar kosong berarti tidak ada batasan. Didit menyimpan setiap origin dalam huruf kecil tanpa port default. Entri yang tidak valid gagal dengan `400` pada `allowed_domains`. Kirim `[]` untuk menghapus batasan.",
                    "example": [
                      "https://app.example.com"
                    ]
                  }
                }
              },
              "examples": {
                "Enable biometric template retention": {
                  "value": {
                    "face_retention_policy": "retain_until_user_deleted",
                    "face_retention_days": 365,
                    "biometric_consent_mode": "auto"
                  }
                },
                "Rotate the legacy secret": {
                  "value": {
                    "rotate_secret_key": true
                  }
                },
                "Set data retention": {
                  "value": {
                    "data_retention_months": 24
                  }
                },
                "Register return hosts": {
                  "value": {
                    "allowed_return_hosts": [
                      "shop.example.com",
                      "app.example.com"
                    ]
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X PATCH 'https://verification.didit.me/v3/webhook/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"face_retention_policy\": \"retain_until_user_deleted\", \"face_retention_days\": 365}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.webhooks.update_config(\n    face_retention_policy=\"retain_until_user_deleted\",\n    face_retention_days=365,\n    biometric_consent_mode=\"auto\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.webhooks.updateConfig({\n  face_retention_policy: \"retain_until_user_deleted\",\n  face_retention_days: 365,\n  biometric_consent_mode: \"auto\",\n});\nconsole.log(result);"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.WebhooksUpdateConfigParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.webhooks().updateConfig(WebhooksUpdateConfigParams.builder()\n        .faceRetentionPolicy(WebhooksUpdateConfigParams.FaceRetentionPolicy.of(\"retain_until_user_deleted\"))\n        .faceRetentionDays(365L)\n        .biometricConsentMode(WebhooksUpdateConfigParams.BiometricConsentMode.of(\"auto\"))\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->webhooks->updateConfig([\n    'face_retention_policy' => 'retain_until_user_deleted',\n    'face_retention_days' => 365,\n    'biometric_consent_mode' => 'auto',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.webhooks.update_config(\n  face_retention_policy: \"retain_until_user_deleted\",\n  face_retention_days: 365,\n  biometric_consent_mode: \"auto\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Webhooks.UpdateConfigAsync(new WebhooksUpdateConfigParams\n{\n    FaceRetentionPolicy = new WebhooksUpdateConfigParamsFaceRetentionPolicy(\"retain_until_user_deleted\"),\n    FaceRetentionDays = 365,\n    BiometricConsentMode = new WebhooksUpdateConfigParamsBiometricConsentMode(\"auto\"),\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "Konfigurasi lengkap setelah pembaruan, dengan struktur yang sama seperti `GET /v3/webhook/`. Saat Anda merotasi rahasia, simpan `secret_shared_key` baru sebelum Anda membuang respons.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookConfig"
                },
                "examples": {
                  "Retention enabled": {
                    "value": {
                      "webhook_url": "https://yourapp.com/webhooks/didit",
                      "webhook_version": "v3",
                      "secret_shared_key": "dGhpcy1pcy10aGUtYXBwLWxldmVsLXNlY3JldC0wMDA",
                      "capture_method": "MOBILE",
                      "data_retention_months": 24,
                      "face_retention_policy": "retain_until_user_deleted",
                      "face_retention_days": 365,
                      "biometric_consent_mode": "auto",
                      "available_events": [
                        {
                          "value": "status.updated",
                          "label": "Session status updated"
                        },
                        {
                          "value": "data.updated",
                          "label": "Session data updated"
                        },
                        {
                          "value": "user.status.updated",
                          "label": "User status updated"
                        },
                        {
                          "value": "user.data.updated",
                          "label": "User data updated"
                        },
                        {
                          "value": "business.status.updated",
                          "label": "Business status updated"
                        },
                        {
                          "value": "business.data.updated",
                          "label": "Business data updated"
                        },
                        {
                          "value": "activity.created",
                          "label": "Activity created"
                        },
                        {
                          "value": "transaction.created",
                          "label": "Transaction created"
                        },
                        {
                          "value": "transaction.status.updated",
                          "label": "Transaction status updated"
                        },
                        {
                          "value": "travel_rule.status.updated",
                          "label": "Travel Rule Status Updated"
                        },
                        {
                          "value": "workflow.compliance_changed",
                          "label": "Workflow Compliance Changed"
                        }
                      ],
                      "allowed_return_hosts": [
                        "shop.example.com"
                      ],
                      "endpoints": [
                        {
                          "uuid": "11111111-2222-3333-4444-555555555555",
                          "label": "Production session webhooks",
                          "url": "https://yourapp.com/webhooks/didit",
                          "enabled": true,
                          "webhook_version": "v3",
                          "secret_shared_key": "dGhpcy1pcy1hbi1leGFtcGxlLXNlY3JldC0wMDAwMDA",
                          "subscribed_events": [
                            "status.updated",
                            "data.updated"
                          ],
                          "created_at": "2026-01-04T08:00:00.000000Z",
                          "updated_at": "2026-04-22T14:09:11.523671Z"
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validasi gagal: setiap kolom yang tidak valid dipetakan ke daftar pesan, dan tidak ada yang diubah. Body yang bukan JSON valid mengembalikan `{\"detail\": \"JSON parse error - ...\"}`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Setiap kolom yang tidak valid dipetakan ke daftar pesan.",
                  "additionalProperties": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Retention days missing": {
                    "value": {
                      "face_retention_days": [
                        "A finite retention duration is required when face retention is enabled."
                      ],
                      "biometric_consent_mode": "auto"
                    }
                  },
                  "Retention window out of range": {
                    "value": {
                      "data_retention_months": [
                        "Ensure this value is less than or equal to 120."
                      ]
                    }
                  },
                  "Invalid return host": {
                    "value": {
                      "allowed_return_hosts": [
                        "'https://shop.example.com' is not a hostname. Register the bare host (e.g. shop.example.com): no scheme, port, path or wildcard."
                      ]
                    }
                  },
                  "Invalid choice": {
                    "value": {
                      "face_retention_policy": [
                        "\"forever\" is not a valid choice."
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Kunci API telah kedaluwarsa: kunci ini dibuat dengan tanggal kedaluwarsa yang telah lewat. Kunci yang salah atau dicabut juga menghasilkan `401`; kunci yang tidak ada menghasilkan `403`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "Pesan kesalahan yang mudah dibaca manusia."
                    }
                  }
                },
                "examples": {
                  "Expired key": {
                    "value": {
                      "detail": "This API key has expired."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Permintaan tidak diizinkan. `x-api-key` yang hilang, tidak valid, atau dicabut akan menghasilkan `You do not have permission to perform this action.` Kunci dengan cakupan terbatas tanpa akses yang dibutuhkan endpoint ini akan menghasilkan pesan yang menyebutkan akses yang hilang, dan kunci yang digunakan dari luar daftar izin IP-nya akan menghasilkan `This API key can't be used from this IP address.`",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "Pesan kesalahan yang mudah dibaca manusia."
                    }
                  }
                },
                "examples": {
                  "Missing or invalid key": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Scoped key without webhooks write": {
                    "value": {
                      "detail": "This API key has no write access to webhooks."
                    }
                  },
                  "Outside the IP allowlist": {
                    "value": {
                      "detail": "This API key can't be used from this IP address."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Batas laju terlampaui: lebih dari 300 permintaan tulis (POST, PATCH, PUT, DELETE) dalam jendela satu menit saat ini untuk kunci API ini. Tunggu `Retry-After` detik sebelum mencoba lagi.",
            "headers": {
              "Retry-After": {
                "description": "Detik untuk menunggu sebelum mencoba lagi.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "example": 30
                }
              },
              "X-RateLimit-Limit": {
                "description": "Permintaan yang diizinkan dalam jendela satu menit (300).",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Permintaan tersisa dalam jendela saat ini.",
                "schema": {
                  "type": "integer",
                  "example": 0
                }
              },
              "X-RateLimit-Reset": {
                "description": "Waktu Unix (detik) saat jendela saat ini direset.",
                "schema": {
                  "type": "integer",
                  "example": 1792056120
                }
              },
              "X-RateLimit-Scope": {
                "description": "Nama anggaran yang terlampaui.",
                "schema": {
                  "type": "string",
                  "example": "generic-write"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "Pesan kesalahan yang mudah dibaca manusia."
                    }
                  }
                },
                "examples": {
                  "Throttled": {
                    "value": {
                      "detail": "Write request rate limit exceeded. You can make up to 300 requests per minute."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/webhook/destinations/{destination_uuid}/analytics/": {
      "get": {
        "summary": "Dapatkan analitik tujuan webhook",
        "description": "Total pengiriman, tingkat kegagalan, dan waktu respons untuk satu tujuan webhook, di seluruh rentang (`summary`) dan per hari UTC (`points`). Setiap upaya dihitung sebagai pengiriman: pengiriman pertama suatu event, setiap [coba lagi](https://docs.didit.me/id/integration/webhooks#kebijakan-coba-lagi) otomatis, dan setiap pengiriman ulang. Pengiriman dianggap gagal jika status HTTP yang tercatat adalah 400 ke atas, sehingga batas waktu habis (tercatat sebagai `504`) dan kegagalan koneksi (`503`) dihitung sebagai gagal; pengiriman yang masih dalam antrean hanya dihitung dalam `total_deliveries`. Catatan pengiriman tersedia selama sekitar 30 hari. Kunci API dengan cakupan membutuhkan `webhooks: read`.",
        "operationId": "get_webhook_destination_analytics",
        "x-didit-sdk": {
          "resource": "webhooks.destinations",
          "method": "retrieve_analytics",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Webhook"
        ],
        "parameters": [
          {
            "name": "destination_uuid",
            "in": "path",
            "required": true,
            "description": "UUID tujuan (`uuid` yang dikembalikan oleh `GET /v3/webhook/destinations/`).",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "11111111-2222-3333-4444-555555555555"
          },
          {
            "name": "date_from",
            "in": "query",
            "required": false,
            "description": "Hari UTC pertama yang disertakan, sebagai `YYYY-MM-DD` (inklusif). Lewati untuk mulai dari pengiriman terlama yang tersedia. `dateFrom` diterima sebagai alias.",
            "schema": {
              "type": "string",
              "format": "date"
            },
            "example": "2026-10-01"
          },
          {
            "name": "date_to",
            "in": "query",
            "required": false,
            "description": "Hari UTC terakhir yang disertakan, sebagai `YYYY-MM-DD` (inklusif). Tidak boleh lebih awal dari `date_from`. `dateTo` diterima sebagai alias.",
            "schema": {
              "type": "string",
              "format": "date"
            },
            "example": "2026-10-16"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/webhook/destinations/11111111-2222-3333-4444-555555555555/analytics/?date_from=2026-10-01&date_to=2026-10-16' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.webhooks.destinations.retrieve_analytics(\n    \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.webhooks.destinations.retrieveAnalytics(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Webhooks.Destinations.RetrieveAnalytics(ctx, \"11111111-2222-3333-4444-555555555555\", didit.WebhooksDestinationsRetrieveAnalyticsParams{})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.webhooks().destinations().retrieveAnalytics(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->webhooks->destinations->retrieveAnalytics('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.webhooks.destinations.retrieve_analytics(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Webhooks.Destinations.RetrieveAnalyticsAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "Statistik pengiriman untuk tujuan.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "summary",
                    "points"
                  ],
                  "properties": {
                    "summary": {
                      "type": "object",
                      "description": "Total selama rentang yang diminta.",
                      "required": [
                        "total_deliveries",
                        "failed_deliveries",
                        "min_response_time_ms",
                        "avg_response_time_ms",
                        "max_response_time_ms",
                        "error_rate_percentage"
                      ],
                      "properties": {
                        "total_deliveries": {
                          "type": "integer",
                          "minimum": 0,
                          "description": "Upaya pengiriman, termasuk yang berada dalam antrean."
                        },
                        "failed_deliveries": {
                          "type": "integer",
                          "minimum": 0,
                          "description": "Percobaan yang status HTTP tercatatnya adalah 400 ke atas."
                        },
                        "min_response_time_ms": {
                          "type": "integer",
                          "nullable": true,
                          "description": "Percobaan tercepat dalam milidetik, atau `null` jika tidak ada percobaan yang memiliki waktu tercatat."
                        },
                        "avg_response_time_ms": {
                          "type": "integer",
                          "nullable": true,
                          "description": "Waktu upaya rata-rata dalam milidetik, dibulatkan, atau `null` jika tidak ada upaya dengan waktu yang tercatat."
                        },
                        "max_response_time_ms": {
                          "type": "integer",
                          "nullable": true,
                          "description": "Upaya paling lambat dalam milidetik, atau `null` jika tidak ada upaya yang memiliki waktu tercatat."
                        },
                        "error_rate_percentage": {
                          "type": "integer",
                          "minimum": 0,
                          "maximum": 100,
                          "description": "`failed_deliveries` / `total_deliveries` x 100, dibulatkan ke bilangan bulat terdekat. `0` ketika tidak ada pengiriman."
                        }
                      }
                    },
                    "points": {
                      "type": "array",
                      "description": "Satu entri per hari UTC yang memiliki pengiriman, yang terlama terlebih dahulu. Hari-hari tanpa pengiriman diabaikan, jadi isi kekosongan tersebut dengan angka nol saat Anda membuat grafiknya.",
                      "items": {
                        "type": "object",
                        "required": [
                          "date",
                          "total_deliveries",
                          "failed_deliveries",
                          "min_response_time_ms",
                          "avg_response_time_ms",
                          "max_response_time_ms"
                        ],
                        "properties": {
                          "date": {
                            "type": "string",
                            "format": "date",
                            "description": "Hari UTC, `YYYY-MM-DD`."
                          },
                          "total_deliveries": {
                            "type": "integer",
                            "minimum": 0,
                            "description": "Upaya pengiriman, termasuk yang berada dalam antrean."
                          },
                          "failed_deliveries": {
                            "type": "integer",
                            "minimum": 0,
                            "description": "Percobaan yang status HTTP tercatatnya adalah 400 ke atas."
                          },
                          "min_response_time_ms": {
                            "type": "integer",
                            "nullable": true,
                            "description": "Percobaan tercepat dalam milidetik, atau `null` jika tidak ada percobaan yang memiliki waktu tercatat."
                          },
                          "avg_response_time_ms": {
                            "type": "integer",
                            "nullable": true,
                            "description": "Waktu upaya rata-rata dalam milidetik, dibulatkan, atau `null` jika tidak ada upaya dengan waktu yang tercatat."
                          },
                          "max_response_time_ms": {
                            "type": "integer",
                            "nullable": true,
                            "description": "Upaya paling lambat dalam milidetik, atau `null` jika tidak ada upaya yang memiliki waktu tercatat."
                          }
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "Three days of deliveries": {
                    "value": {
                      "summary": {
                        "total_deliveries": 1250,
                        "failed_deliveries": 12,
                        "min_response_time_ms": 38,
                        "avg_response_time_ms": 164,
                        "max_response_time_ms": 5004,
                        "error_rate_percentage": 1
                      },
                      "points": [
                        {
                          "date": "2026-10-14",
                          "total_deliveries": 410,
                          "failed_deliveries": 0,
                          "min_response_time_ms": 38,
                          "avg_response_time_ms": 152,
                          "max_response_time_ms": 911
                        },
                        {
                          "date": "2026-10-15",
                          "total_deliveries": 395,
                          "failed_deliveries": 12,
                          "min_response_time_ms": 41,
                          "avg_response_time_ms": 190,
                          "max_response_time_ms": 5004
                        },
                        {
                          "date": "2026-10-16",
                          "total_deliveries": 445,
                          "failed_deliveries": 0,
                          "min_response_time_ms": 40,
                          "avg_response_time_ms": 151,
                          "max_response_time_ms": 1220
                        }
                      ]
                    }
                  },
                  "No deliveries in range": {
                    "value": {
                      "summary": {
                        "total_deliveries": 0,
                        "failed_deliveries": 0,
                        "min_response_time_ms": null,
                        "avg_response_time_ms": null,
                        "max_response_time_ms": null,
                        "error_rate_percentage": 0
                      },
                      "points": []
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "`date_from` atau `date_to` bukan tanggal berformat `YYYY-MM-DD`, atau `date_to` lebih awal daripada `date_from`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Setiap kolom yang tidak valid dipetakan ke daftar pesan.",
                  "additionalProperties": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Malformed date": {
                    "value": {
                      "date_from": [
                        "Date has wrong format. Use one of these formats instead: YYYY-MM-DD."
                      ]
                    }
                  },
                  "Reversed range": {
                    "value": {
                      "date_to": [
                        "date_to must be greater than or equal to date_from."
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Kunci API telah kedaluwarsa: kunci ini dibuat dengan tanggal kedaluwarsa yang telah lewat. Kunci yang salah atau dicabut juga menghasilkan `401`; kunci yang tidak ada menghasilkan `403`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "Pesan kesalahan yang mudah dibaca manusia."
                    }
                  }
                },
                "examples": {
                  "Expired key": {
                    "value": {
                      "detail": "This API key has expired."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Permintaan tidak diizinkan. `x-api-key` yang hilang, tidak valid, atau dicabut akan menghasilkan `You do not have permission to perform this action.` Kunci dengan cakupan terbatas tanpa akses yang dibutuhkan endpoint ini akan menghasilkan pesan yang menyebutkan akses yang hilang, dan kunci yang digunakan dari luar daftar izin IP-nya akan menghasilkan `This API key can't be used from this IP address.`",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "Pesan kesalahan yang mudah dibaca manusia."
                    }
                  }
                },
                "examples": {
                  "Missing or invalid key": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Scoped key without webhooks read": {
                    "value": {
                      "detail": "This API key has no read access to webhooks."
                    }
                  },
                  "Outside the IP allowlist": {
                    "value": {
                      "detail": "This API key can't be used from this IP address."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Tidak ada tujuan dengan UUID ini untuk aplikasi tersebut, atau tujuan tersebut telah dihapus.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "Pesan kesalahan yang mudah dibaca manusia."
                    }
                  }
                },
                "examples": {
                  "Destination not found": {
                    "value": {
                      "detail": "Webhook destination not found."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Batas laju terlampaui: lebih dari 600 permintaan GET dalam jendela satu menit saat ini untuk kunci API ini. Tunggu `Retry-After` detik sebelum mencoba lagi.",
            "headers": {
              "Retry-After": {
                "description": "Detik untuk menunggu sebelum mencoba lagi.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "example": 30
                }
              },
              "X-RateLimit-Limit": {
                "description": "Permintaan yang diizinkan dalam jendela satu menit (600).",
                "schema": {
                  "type": "integer",
                  "example": 600
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Permintaan tersisa dalam jendela saat ini.",
                "schema": {
                  "type": "integer",
                  "example": 0
                }
              },
              "X-RateLimit-Reset": {
                "description": "Waktu Unix (detik) saat jendela saat ini direset.",
                "schema": {
                  "type": "integer",
                  "example": 1792056120
                }
              },
              "X-RateLimit-Scope": {
                "description": "Nama anggaran yang terlampaui.",
                "schema": {
                  "type": "string",
                  "example": "generic-get"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "Pesan kesalahan yang mudah dibaca manusia."
                    }
                  }
                },
                "examples": {
                  "Throttled": {
                    "value": {
                      "detail": "GET request rate limit exceeded. You can make up to 600 requests per minute."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/webhook/destinations/{destination_uuid}/deliveries/": {
      "get": {
        "summary": "Daftar pengiriman ke tujuan webhook",
        "description": "Telusuri setiap upaya pengiriman ke satu tujuan webhook, yang terbaru terlebih dahulu. Pengiriman pertama dari setiap event, setiap [coba lagi](https://docs.didit.me/id/integration/webhooks#kebijakan-coba-lagi) otomatis, dan setiap pengiriman ulang adalah entri terpisah. Entri memuat status HTTP dan waktu respons tetapi bukan payload: ambil satu pengiriman untuk membaca header dan isinya. `count` akurat hingga 100 dan terbaca 100 di atas itu, jadi ikuti `next` hingga bernilai `null`. Rekaman pengiriman tersedia selama sekitar 30 hari. Kunci API dengan cakupan membutuhkan `webhooks: read` dan `decisions: read`; kunci yang dibatasi untuk beberapa alur kerja atau untuk sesi yang disetujui tidak dapat menggunakan endpoint ini.",
        "operationId": "list_webhook_destination_deliveries",
        "x-didit-sdk": {
          "resource": "webhooks.destinations",
          "method": "list_deliveries",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Webhook"
        ],
        "parameters": [
          {
            "name": "destination_uuid",
            "in": "path",
            "required": true,
            "description": "UUID tujuan (`uuid` yang dikembalikan oleh `GET /v3/webhook/destinations/`).",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "11111111-2222-3333-4444-555555555555"
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Jumlah pengiriman maksimum per halaman. Defaultnya 50. Nilai yang bukan bilangan bulat positif akan dialihkan ke 50; nilai di atas 1000000 mengembalikan `400`.",
            "schema": {
              "type": "integer",
              "default": 50,
              "minimum": 1,
              "maximum": 1000000
            },
            "example": 50
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "description": "Jumlah pengiriman yang dilewati. Default-nya 0. Lebih disarankan mengikuti URL `next` dan `previous` dari respons.",
            "schema": {
              "type": "integer",
              "default": 0,
              "minimum": 0,
              "maximum": 1000000
            },
            "example": 0
          },
          {
            "name": "date_from",
            "in": "query",
            "required": false,
            "description": "Hari UTC pertama yang disertakan, sebagai `YYYY-MM-DD` (inklusif). Lewati untuk mulai dari pengiriman terlama yang tersedia. `dateFrom` diterima sebagai alias.",
            "schema": {
              "type": "string",
              "format": "date"
            },
            "example": "2026-10-01"
          },
          {
            "name": "date_to",
            "in": "query",
            "required": false,
            "description": "Hari UTC terakhir yang disertakan, sebagai `YYYY-MM-DD` (inklusif). Tidak boleh lebih awal dari `date_from`. `dateTo` diterima sebagai alias.",
            "schema": {
              "type": "string",
              "format": "date"
            },
            "example": "2026-10-16"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/webhook/destinations/11111111-2222-3333-4444-555555555555/deliveries/?limit=50&date_from=2026-10-01' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nfor item in client.webhooks.destinations.list_deliveries(\n    \"11111111-2222-3333-4444-555555555555\",\n):\n    print(item)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nfor await (const item of didit.webhooks.destinations.listDeliveries(\"11111111-2222-3333-4444-555555555555\")) {\n  console.log(item);\n}"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\niter := client.Webhooks.Destinations.ListDeliveriesAutoPaging(ctx, \"11111111-2222-3333-4444-555555555555\", didit.WebhooksDestinationsListDeliveriesParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nfor (var item : client.webhooks().destinations().listDeliveries(\"11111111-2222-3333-4444-555555555555\")) {\n    System.out.println(item);\n}"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\nforeach ($didit->webhooks->destinations->listDeliveries('11111111-2222-3333-4444-555555555555') as $item) {\n    print_r($item->toArray());\n}"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.webhooks.destinations.list_deliveries(\"11111111-2222-3333-4444-555555555555\").auto_paging_each do |item|\n  puts item.to_h\nend"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.Webhooks.Destinations.ListDeliveriesAsync(\"11111111-2222-3333-4444-555555555555\"))\n{\n    Console.WriteLine(JsonSerializer.Serialize(item));\n}"
          }
        ],
        "responses": {
          "200": {
            "description": "Satu halaman pengiriman, terbaru lebih dahulu.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "count",
                    "next",
                    "previous",
                    "results"
                  ],
                  "properties": {
                    "count": {
                      "type": "integer",
                      "minimum": 0,
                      "description": "Pengiriman yang cocok, jumlahnya tepat hingga 100 dan dibatasi maksimal 100 setelah itu. Gunakan `next` untuk mengetahui apakah masih ada halaman lainnya."
                    },
                    "next": {
                      "type": "string",
                      "format": "uri",
                      "nullable": true,
                      "description": "URL absolut halaman berikutnya, atau `null` di halaman terakhir."
                    },
                    "previous": {
                      "type": "string",
                      "format": "uri",
                      "nullable": true,
                      "description": "URL absolut halaman sebelumnya, atau `null` di halaman pertama."
                    },
                    "results": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/WebhookDestinationDelivery"
                      }
                    }
                  }
                },
                "examples": {
                  "Failed delivery, its retry and a queued event": {
                    "value": {
                      "count": 3,
                      "next": null,
                      "previous": null,
                      "results": [
                        {
                          "uuid": "66666666-7777-8888-9999-000000000003",
                          "session_id": null,
                          "request_url": "https://yourapp.com/webhooks/didit",
                          "response_status": null,
                          "response_time_ms": null,
                          "status": "APPROVED",
                          "webhook_type": "transaction.created",
                          "created_at": "2026-10-15T09:23:02.871190Z"
                        },
                        {
                          "uuid": "66666666-7777-8888-9999-000000000002",
                          "session_id": "22222222-3333-4444-5555-666666666666",
                          "request_url": "https://yourapp.com/webhooks/didit",
                          "response_status": 200,
                          "response_time_ms": 143,
                          "status": "In Progress",
                          "webhook_type": "status.updated",
                          "created_at": "2026-10-15T09:22:19.104233Z"
                        },
                        {
                          "uuid": "66666666-7777-8888-9999-000000000001",
                          "session_id": "22222222-3333-4444-5555-666666666666",
                          "request_url": "https://yourapp.com/webhooks/didit",
                          "response_status": 503,
                          "response_time_ms": 412,
                          "status": "In Progress",
                          "webhook_type": "status.updated",
                          "created_at": "2026-10-15T09:21:18.412345Z"
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "`date_from` atau `date_to` bukan tanggal berformat `YYYY-MM-DD`, `date_to` lebih awal daripada `date_from`, atau `limit` atau `offset` bernilai di atas 1000000 (kesalahan tersebut berupa array pesan JSON).",
            "content": {
              "application/json": {
                "examples": {
                  "Malformed date": {
                    "value": {
                      "date_from": [
                        "Date has wrong format. Use one of these formats instead: YYYY-MM-DD."
                      ]
                    }
                  },
                  "Reversed range": {
                    "value": {
                      "date_to": [
                        "date_to must be greater than or equal to date_from."
                      ]
                    }
                  },
                  "Limit too large": {
                    "value": [
                      "limit must not exceed 1000000."
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Kunci API telah kedaluwarsa: kunci ini dibuat dengan tanggal kedaluwarsa yang telah lewat. Kunci yang salah atau dicabut juga menghasilkan `401`; kunci yang tidak ada menghasilkan `403`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "Pesan kesalahan yang mudah dibaca manusia."
                    }
                  }
                },
                "examples": {
                  "Expired key": {
                    "value": {
                      "detail": "This API key has expired."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Permintaan tidak diizinkan. `x-api-key` yang hilang, tidak valid, atau dicabut akan menghasilkan `You do not have permission to perform this action.` Kunci dengan cakupan terbatas tanpa akses yang dibutuhkan endpoint ini akan menghasilkan pesan yang menyebutkan akses yang hilang, dan kunci yang digunakan dari luar daftar izin IP-nya akan menghasilkan `This API key can't be used from this IP address.` Kunci yang dibatasi untuk beberapa alur kerja tertentu atau sesi yang disetujui akan menghasilkan `This API key only reaches sessions inside its workflow or status limits, so it can't use this endpoint.`",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "Pesan kesalahan yang mudah dibaca manusia."
                    }
                  }
                },
                "examples": {
                  "Missing or invalid key": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Scoped key without webhooks read": {
                    "value": {
                      "detail": "This API key has no read access to webhooks."
                    }
                  },
                  "Scoped key without decisions read": {
                    "value": {
                      "detail": "This API key has no read access to decisions."
                    }
                  },
                  "Key limited to workflows or approved sessions": {
                    "value": {
                      "detail": "This API key only reaches sessions inside its workflow or status limits, so it can't use this endpoint."
                    }
                  },
                  "Outside the IP allowlist": {
                    "value": {
                      "detail": "This API key can't be used from this IP address."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Tidak ada tujuan dengan UUID ini untuk aplikasi tersebut, atau tujuan tersebut telah dihapus.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "Pesan kesalahan yang mudah dibaca manusia."
                    }
                  }
                },
                "examples": {
                  "Destination not found": {
                    "value": {
                      "detail": "Webhook destination not found."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Batas laju terlampaui: lebih dari 600 permintaan GET dalam jendela satu menit saat ini untuk kunci API ini. Tunggu `Retry-After` detik sebelum mencoba lagi.",
            "headers": {
              "Retry-After": {
                "description": "Detik untuk menunggu sebelum mencoba lagi.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "example": 30
                }
              },
              "X-RateLimit-Limit": {
                "description": "Permintaan yang diizinkan dalam jendela satu menit (600).",
                "schema": {
                  "type": "integer",
                  "example": 600
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Permintaan tersisa dalam jendela saat ini.",
                "schema": {
                  "type": "integer",
                  "example": 0
                }
              },
              "X-RateLimit-Reset": {
                "description": "Waktu Unix (detik) saat jendela saat ini direset.",
                "schema": {
                  "type": "integer",
                  "example": 1792056120
                }
              },
              "X-RateLimit-Scope": {
                "description": "Nama anggaran yang terlampaui.",
                "schema": {
                  "type": "string",
                  "example": "generic-get"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "Pesan kesalahan yang mudah dibaca manusia."
                    }
                  }
                },
                "examples": {
                  "Throttled": {
                    "value": {
                      "detail": "GET request rate limit exceeded. You can make up to 600 requests per minute."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/webhook/destinations/{destination_uuid}/deliveries/{delivery_uuid}/": {
      "get": {
        "summary": "Dapatkan pengiriman tujuan webhook",
        "description": "Ambil satu percobaan pengiriman ke tujuan webhook dengan header permintaan dan isi JSON yang persis dikirimkan Didit, status HTTP yang dikembalikan endpoint Anda, serta waktu respons. `request_header` dan `request_body` berupa teks JSON: parsing keduanya untuk membaca header tanda tangan dan payload, misalnya untuk memeriksa [verifikasi tanda tangan](https://docs.didit.me/id/integration/webhooks#verifikasi-tanda-tangan) Anda terhadap `secret_shared_key` milik tujuan. Pengiriman tidak pernah berisi rahasia penandatanganan, dan Didit tidak mencatat isi respons endpoint Anda. Kunci API dengan pembatasan cakupan memerlukan `webhooks: read` dan `decisions: read`; kunci yang terbatas pada alur kerja tertentu atau sesi yang disetujui tidak dapat menggunakan endpoint ini.",
        "operationId": "get_webhook_destination_delivery",
        "x-didit-sdk": {
          "resource": "webhooks.destinations",
          "method": "retrieve_delivery",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Webhook"
        ],
        "parameters": [
          {
            "name": "destination_uuid",
            "in": "path",
            "required": true,
            "description": "UUID tujuan yang menjadi tujuan pengiriman tersebut.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "11111111-2222-3333-4444-555555555555"
          },
          {
            "name": "delivery_uuid",
            "in": "path",
            "required": true,
            "description": "UUID pengiriman: `uuid` dari entri yang dikembalikan oleh `GET /v3/webhook/destinations/{destination_uuid}/deliveries/`.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "66666666-7777-8888-9999-000000000001"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/webhook/destinations/11111111-2222-3333-4444-555555555555/deliveries/66666666-7777-8888-9999-000000000001/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.webhooks.destinations.retrieve_delivery(\n    \"11111111-2222-3333-4444-555555555555\",\n    \"66666666-7777-8888-9999-000000000001\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.webhooks.destinations.retrieveDelivery(\n  \"11111111-2222-3333-4444-555555555555\",\n  \"66666666-7777-8888-9999-000000000001\",\n);\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Webhooks.Destinations.RetrieveDelivery(ctx, \"11111111-2222-3333-4444-555555555555\", \"66666666-7777-8888-9999-000000000001\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.webhooks().destinations().retrieveDelivery(\"11111111-2222-3333-4444-555555555555\", \"66666666-7777-8888-9999-000000000001\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->webhooks->destinations->retrieveDelivery('11111111-2222-3333-4444-555555555555', '66666666-7777-8888-9999-000000000001');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.webhooks.destinations.retrieve_delivery(\n  \"11111111-2222-3333-4444-555555555555\",\n  \"66666666-7777-8888-9999-000000000001\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Webhooks.Destinations.RetrieveDeliveryAsync(\"11111111-2222-3333-4444-555555555555\", \"66666666-7777-8888-9999-000000000001\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "Pengiriman, beserta header dan body permintaannya.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookDestinationDeliveryDetail"
                },
                "examples": {
                  "Connection failure": {
                    "value": {
                      "uuid": "66666666-7777-8888-9999-000000000001",
                      "session_id": "22222222-3333-4444-5555-666666666666",
                      "request_url": "https://yourapp.com/webhooks/didit",
                      "response_status": 503,
                      "response_time_ms": 412,
                      "status": "In Progress",
                      "webhook_type": "status.updated",
                      "created_at": "2026-10-15T09:21:18.412345Z",
                      "request_header": "{\"Content-Type\": \"application/json\", \"X-Signature\": \"a5e02a03404e1337a0198e6be15d34abbd053c658a0e51e5d0e78554213ef29b\", \"X-Signature-V2\": \"927e7cb770c94ce745939bff73f04aa200015f3bc64795ba46c2aaf78a6cedc5\", \"X-Signature-Simple\": \"e37b0d4c716c72bb5ae7127b9cc455d28ab4686e9e22312b4ec2327409a73302\", \"X-Timestamp\": \"1792056078\", \"User-Agent\": \"DiditWebhook/2.0 +https://didit.me\"}",
                      "request_body": "{\"application_id\":\"aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee\",\"created_at\":1792056057,\"environment\":\"live\",\"event_id\":\"33333333-4444-5555-6666-777777777777\",\"sandbox_scenario\":null,\"session_id\":\"22222222-3333-4444-5555-666666666666\",\"status\":\"In Progress\",\"timestamp\":1792056078,\"vendor_data\":\"user-123\",\"webhook_type\":\"status.updated\",\"workflow_id\":\"44444444-5555-6666-7777-888888888888\",\"workflow_version\":3}"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Kunci API telah kedaluwarsa: kunci ini dibuat dengan tanggal kedaluwarsa yang telah lewat. Kunci yang salah atau dicabut juga menghasilkan `401`; kunci yang tidak ada menghasilkan `403`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "Pesan kesalahan yang mudah dibaca manusia."
                    }
                  }
                },
                "examples": {
                  "Expired key": {
                    "value": {
                      "detail": "This API key has expired."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Permintaan tidak diizinkan. `x-api-key` yang hilang, tidak valid, atau dicabut akan menghasilkan `You do not have permission to perform this action.` Kunci dengan cakupan terbatas tanpa akses yang dibutuhkan endpoint ini akan menghasilkan pesan yang menyebutkan akses yang hilang, dan kunci yang digunakan dari luar daftar izin IP-nya akan menghasilkan `This API key can't be used from this IP address.` Kunci yang dibatasi untuk beberapa alur kerja tertentu atau sesi yang disetujui akan menghasilkan `This API key only reaches sessions inside its workflow or status limits, so it can't use this endpoint.`",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "Pesan kesalahan yang mudah dibaca manusia."
                    }
                  }
                },
                "examples": {
                  "Missing or invalid key": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Scoped key without webhooks read": {
                    "value": {
                      "detail": "This API key has no read access to webhooks."
                    }
                  },
                  "Scoped key without decisions read": {
                    "value": {
                      "detail": "This API key has no read access to decisions."
                    }
                  },
                  "Key limited to workflows or approved sessions": {
                    "value": {
                      "detail": "This API key only reaches sessions inside its workflow or status limits, so it can't use this endpoint."
                    }
                  },
                  "Outside the IP allowlist": {
                    "value": {
                      "detail": "This API key can't be used from this IP address."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Tujuan tidak ada untuk aplikasi ini atau telah dihapus, atau pengiriman tidak ada, milik tujuan lain, atau tidak lagi tersedia.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "Pesan kesalahan yang mudah dibaca manusia."
                    }
                  }
                },
                "examples": {
                  "Destination not found": {
                    "value": {
                      "detail": "Webhook destination not found."
                    }
                  },
                  "Delivery not found": {
                    "value": {
                      "detail": "Webhook delivery not found."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Batas laju terlampaui: lebih dari 600 permintaan GET dalam jendela satu menit saat ini untuk kunci API ini. Tunggu `Retry-After` detik sebelum mencoba lagi.",
            "headers": {
              "Retry-After": {
                "description": "Detik untuk menunggu sebelum mencoba lagi.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "example": 30
                }
              },
              "X-RateLimit-Limit": {
                "description": "Permintaan yang diizinkan dalam jendela satu menit (600).",
                "schema": {
                  "type": "integer",
                  "example": 600
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Permintaan tersisa dalam jendela saat ini.",
                "schema": {
                  "type": "integer",
                  "example": 0
                }
              },
              "X-RateLimit-Reset": {
                "description": "Waktu Unix (detik) saat jendela saat ini direset.",
                "schema": {
                  "type": "integer",
                  "example": 1792056120
                }
              },
              "X-RateLimit-Scope": {
                "description": "Nama anggaran yang terlampaui.",
                "schema": {
                  "type": "string",
                  "example": "generic-get"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "Pesan kesalahan yang mudah dibaca manusia."
                    }
                  }
                },
                "examples": {
                  "Throttled": {
                    "value": {
                      "detail": "GET request rate limit exceeded. You can make up to 600 requests per minute."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/webhook/destinations/{destination_uuid}/deliveries/{delivery_uuid}/resend/": {
      "post": {
        "summary": "Kirim ulang pengiriman ke tujuan webhook",
        "description": "Kirim ulang pengiriman sebelumnya, misalnya setelah endpoint Anda sempat tidak aktif. Didit mengambil payload yang tersimpan, menetapkan `timestamp` baru, menandatanganinya kembali dengan `secret_shared_key` tujuan saat ini (`X-Signature`, `X-Signature-V2`, `X-Signature-Simple`, dan `X-Timestamp`), dan mengirimkannya ke `request_url` pengiriman, bahkan jika URL tujuan telah berubah sejak saat itu atau tujuan dinonaktifkan. `event_id` dan bagian payload lainnya tidak berubah, jadi lakukan deduplikasi pada `event_id`. Pemanggilan menunggu hingga 5 detik untuk endpoint Anda dan mengembalikan pengiriman baru dengan `200` apa pun jawaban endpoint Anda: baca `response_status`. Pengiriman ulang tidak dicoba lagi secara otomatis, setiap pemanggilan mengirim ulang dan membuat pengiriman baru, dan permintaan tidak memiliki isi. Kunci API dengan cakupan memerlukan `webhooks: write` dan `decisions: read`; kunci yang terbatas pada beberapa alur kerja atau sesi yang disetujui tidak dapat menggunakan endpoint ini.",
        "operationId": "resend_webhook_destination_delivery",
        "x-didit-sdk": {
          "resource": "webhooks.destinations",
          "method": "resend_delivery",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Webhook"
        ],
        "parameters": [
          {
            "name": "destination_uuid",
            "in": "path",
            "required": true,
            "description": "UUID tujuan yang menjadi tujuan pengiriman tersebut.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "11111111-2222-3333-4444-555555555555"
          },
          {
            "name": "delivery_uuid",
            "in": "path",
            "required": true,
            "description": "UUID pengiriman yang akan dikirim ulang: `uuid` dari entri yang dikembalikan oleh `GET /v3/webhook/destinations/{destination_uuid}/deliveries/`.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "66666666-7777-8888-9999-000000000001"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://verification.didit.me/v3/webhook/destinations/11111111-2222-3333-4444-555555555555/deliveries/66666666-7777-8888-9999-000000000001/resend/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.webhooks.destinations.resend_delivery(\n    \"11111111-2222-3333-4444-555555555555\",\n    \"66666666-7777-8888-9999-000000000001\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.webhooks.destinations.resendDelivery(\n  \"11111111-2222-3333-4444-555555555555\",\n  \"66666666-7777-8888-9999-000000000001\",\n);\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Webhooks.Destinations.ResendDelivery(ctx, \"11111111-2222-3333-4444-555555555555\", \"66666666-7777-8888-9999-000000000001\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.webhooks().destinations().resendDelivery(\"11111111-2222-3333-4444-555555555555\", \"66666666-7777-8888-9999-000000000001\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->webhooks->destinations->resendDelivery('11111111-2222-3333-4444-555555555555', '66666666-7777-8888-9999-000000000001');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.webhooks.destinations.resend_delivery(\n  \"11111111-2222-3333-4444-555555555555\",\n  \"66666666-7777-8888-9999-000000000001\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Webhooks.Destinations.ResendDeliveryAsync(\"11111111-2222-3333-4444-555555555555\", \"66666666-7777-8888-9999-000000000001\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "Pengiriman baru, yang sudah dicoba. `response_status` adalah respons yang diberikan endpoint Anda kali ini (`504` batas waktu habis, `503` kegagalan koneksi). Pengiriman asli tidak berubah.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookDestinationDeliveryDetail"
                },
                "examples": {
                  "Accepted on resend": {
                    "value": {
                      "uuid": "66666666-7777-8888-9999-000000000004",
                      "session_id": "22222222-3333-4444-5555-666666666666",
                      "request_url": "https://yourapp.com/webhooks/didit",
                      "response_status": 200,
                      "response_time_ms": 151,
                      "status": "In Progress",
                      "webhook_type": "status.updated",
                      "created_at": "2026-10-16T14:05:42.330981Z",
                      "request_header": "{\"Content-Type\": \"application/json\", \"X-Signature\": \"b8eb1e376517ee0cad8ba98ff7f8fd35fc72eca231000963a96a335f82328835\", \"X-Signature-V2\": \"9efd2ce9ed1303e1d05273ef9608a59363ed9789a05253db4748b3e8e50cb109\", \"X-Signature-Simple\": \"bf3a9dc04b2c20ab539203b0cd5cca2a10f630bf62d8feb6d68d82af80f64774\", \"X-Timestamp\": \"1792159542\", \"User-Agent\": \"DiditWebhook/2.0 +https://didit.me\"}",
                      "request_body": "{\"application_id\":\"aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee\",\"created_at\":1792056057,\"environment\":\"live\",\"event_id\":\"33333333-4444-5555-6666-777777777777\",\"sandbox_scenario\":null,\"session_id\":\"22222222-3333-4444-5555-666666666666\",\"status\":\"In Progress\",\"timestamp\":1792159542,\"vendor_data\":\"user-123\",\"webhook_type\":\"status.updated\",\"workflow_id\":\"44444444-5555-6666-7777-888888888888\",\"workflow_version\":3}"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Pengiriman yang tersimpan tidak dapat ditandatangani lagi. Tidak ada yang dikirim.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "Pesan kesalahan yang mudah dibaca manusia."
                    },
                    "code": {
                      "type": "string",
                      "description": "Kode error stabil yang dapat dibaca mesin. Buat percabangan logika berdasarkan ini, bukan pada `detail`."
                    }
                  }
                },
                "examples": {
                  "Unsignable delivery": {
                    "value": {
                      "detail": "Invalid webhook data format",
                      "code": "invalid_webhook_payload"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Kunci API telah kedaluwarsa: kunci ini dibuat dengan tanggal kedaluwarsa yang telah lewat. Kunci yang salah atau dicabut juga menghasilkan `401`; kunci yang tidak ada menghasilkan `403`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "Pesan kesalahan yang mudah dibaca manusia."
                    }
                  }
                },
                "examples": {
                  "Expired key": {
                    "value": {
                      "detail": "This API key has expired."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Permintaan tidak diizinkan. `x-api-key` yang hilang, tidak valid, atau dicabut akan menghasilkan `You do not have permission to perform this action.` Kunci dengan cakupan terbatas tanpa akses yang dibutuhkan endpoint ini akan menghasilkan pesan yang menyebutkan akses yang hilang, dan kunci yang digunakan dari luar daftar izin IP-nya akan menghasilkan `This API key can't be used from this IP address.` Kunci yang dibatasi untuk beberapa alur kerja tertentu atau sesi yang disetujui akan menghasilkan `This API key only reaches sessions inside its workflow or status limits, so it can't use this endpoint.`",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "Pesan kesalahan yang mudah dibaca manusia."
                    }
                  }
                },
                "examples": {
                  "Missing or invalid key": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Scoped key without webhooks write": {
                    "value": {
                      "detail": "This API key has no write access to webhooks."
                    }
                  },
                  "Scoped key without decisions read": {
                    "value": {
                      "detail": "This API key has no read access to decisions."
                    }
                  },
                  "Key limited to workflows or approved sessions": {
                    "value": {
                      "detail": "This API key only reaches sessions inside its workflow or status limits, so it can't use this endpoint."
                    }
                  },
                  "Outside the IP allowlist": {
                    "value": {
                      "detail": "This API key can't be used from this IP address."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Tujuan tidak ada untuk aplikasi ini atau telah dihapus, atau pengiriman tidak ada, milik tujuan lain, atau tidak lagi tersedia.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "Pesan kesalahan yang mudah dibaca manusia."
                    }
                  }
                },
                "examples": {
                  "Destination not found": {
                    "value": {
                      "detail": "Webhook destination not found."
                    }
                  },
                  "Delivery not found": {
                    "value": {
                      "detail": "Webhook delivery not found."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Batas laju terlampaui: lebih dari 300 permintaan tulis (POST, PATCH, PUT, DELETE) dalam jendela satu menit saat ini untuk kunci API ini. Tunggu `Retry-After` detik sebelum mencoba lagi.",
            "headers": {
              "Retry-After": {
                "description": "Detik untuk menunggu sebelum mencoba lagi.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "example": 30
                }
              },
              "X-RateLimit-Limit": {
                "description": "Permintaan yang diizinkan dalam jendela satu menit (300).",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Permintaan tersisa dalam jendela saat ini.",
                "schema": {
                  "type": "integer",
                  "example": 0
                }
              },
              "X-RateLimit-Reset": {
                "description": "Waktu Unix (detik) saat jendela saat ini direset.",
                "schema": {
                  "type": "integer",
                  "example": 1792056120
                }
              },
              "X-RateLimit-Scope": {
                "description": "Nama anggaran yang terlampaui.",
                "schema": {
                  "type": "string",
                  "example": "generic-write"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "Pesan kesalahan yang mudah dibaca manusia."
                    }
                  }
                },
                "examples": {
                  "Throttled": {
                    "value": {
                      "detail": "Write request rate limit exceeded. You can make up to 300 requests per minute."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/events/": {
      "get": {
        "summary": "Mencantumkan event pemantauan",
        "description": "Mencantumkan daftar event pemantauan yang disimpan untuk aplikasi Anda, `occurred_at` terbaru lebih dahulu, dengan filter opsional yang digabungkan dengan AND. Filter multi-nilai (`event_category`, `action_type`, `status`, `retention_class`) mengulang parameter dan mencocokkan salah satu nilainya; filter lainnya merupakan pencocokan persis, dan nilai yang tidak dikenal tidak mengembalikan event apa pun. Setiap hasil adalah ringkasan: panggil `GET /v3/events/{event_uuid}/` untuk payload, konteks perangkat, pengayaan IP, dan bukti aturan, serta utamakan `GET /v3/events/subjects/{vendor_data}/` untuk riwayat satu subjek. Pembacaan berfungsi terlepas dari apakah penyerapan event diaktifkan atau tidak. Kunci API dengan pembatasan cakupan memerlukan `transactions: read`. Lihat [Penyerapan event](https://docs.didit.me/id/transaction-monitoring/events).",
        "operationId": "list_monitoring_events",
        "x-didit-sdk": {
          "resource": "monitoring_events",
          "method": "list",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Monitoring Events"
        ],
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Jumlah event maksimum per halaman. Defaultnya 50. Nilai di atas 1000000 mengembalikan `400`; nilai non-numerik, nol, atau negatif akan dialihkan ke 50.",
            "schema": {
              "type": "integer",
              "default": 50,
              "minimum": 1,
              "maximum": 1000000
            },
            "example": 50
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "description": "Jumlah event yang dilewati. Default-nya 0. Lebih disarankan mengikuti URL `next` dari respons.",
            "schema": {
              "type": "integer",
              "default": 0,
              "minimum": 0,
              "maximum": 1000000
            },
            "example": 0
          },
          {
            "name": "event_category",
            "in": "query",
            "required": false,
            "description": "Hanya event dalam kategori ini. Ulangi parameter untuk beberapa nilai (`?event_category=payment&event_category=dispute`); event yang cocok dengan salah satunya akan dikembalikan.",
            "style": "form",
            "explode": true,
            "schema": {
              "type": "array",
              "items": {
                "type": "string",
                "enum": [
                  "auth",
                  "session",
                  "gameplay",
                  "bonus",
                  "affiliate",
                  "payment",
                  "dispute",
                  "security",
                  "responsible_gambling",
                  "custom"
                ]
              }
            },
            "example": [
              "payment",
              "dispute"
            ]
          },
          {
            "name": "action_type",
            "in": "query",
            "required": false,
            "description": "Hanya event dengan jenis tindakan ini (persis, peka huruf besar-kecil). Ulangi untuk beberapa nilai.",
            "style": "form",
            "explode": true,
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "example": [
              "deposit_completed",
              "chargeback_opened"
            ]
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "description": "Hanya event dengan status ini. Ulangi untuk beberapa nilai.",
            "style": "form",
            "explode": true,
            "schema": {
              "type": "array",
              "items": {
                "type": "string",
                "enum": [
                  "ACCEPTED",
                  "APPROVED",
                  "IN_REVIEW",
                  "DECLINED"
                ]
              }
            },
            "example": [
              "IN_REVIEW",
              "DECLINED"
            ]
          },
          {
            "name": "retention_class",
            "in": "query",
            "required": false,
            "description": "Hanya event dalam kelas retensi ini. Ulangi untuk beberapa nilai.",
            "style": "form",
            "explode": true,
            "schema": {
              "type": "array",
              "items": {
                "type": "string",
                "enum": [
                  "low_value",
                  "standard",
                  "risk_relevant",
                  "monetary_or_compliance"
                ]
              }
            },
            "example": [
              "risk_relevant"
            ]
          },
          {
            "name": "subject_vendor_data",
            "in": "query",
            "required": false,
            "description": "Kecocokan persis pada `vendor_data` subjek. ID yang sama dapat menamai individu dan perusahaan; tambahkan `subject_entity_type` untuk memilih salah satu, atau gunakan `GET /v3/events/subjects/{vendor_data}/`.",
            "schema": {
              "type": "string"
            },
            "example": "user-42"
          },
          {
            "name": "subject_entity_type",
            "in": "query",
            "required": false,
            "description": "`company` hanya mengembalikan event dari subjek perusahaan; nilai non-kosong lainnya (misalnya `individual`) hanya mengembalikan event dari perorangan. Jangan sertakan untuk mengembalikan keduanya.",
            "schema": {
              "type": "string",
              "enum": [
                "individual",
                "company"
              ]
            },
            "example": "individual"
          },
          {
            "name": "business_vendor_data",
            "in": "query",
            "required": false,
            "description": "Kecocokan persis pada `business.vendor_data` yang dikirim bersama event.",
            "schema": {
              "type": "string"
            },
            "example": "merchant-7"
          },
          {
            "name": "session_id",
            "in": "query",
            "required": false,
            "description": "Kecocokan persis pada `session.session_id`.",
            "schema": {
              "type": "string"
            },
            "example": "web-session-abc"
          },
          {
            "name": "device_fingerprint",
            "in": "query",
            "required": false,
            "description": "Kecocokan persis pada `device_context.fingerprint`.",
            "schema": {
              "type": "string"
            },
            "example": "fp-a8c1"
          },
          {
            "name": "ip_address",
            "in": "query",
            "required": false,
            "description": "Kecocokan persis pada alamat IP peristiwa.",
            "schema": {
              "type": "string"
            },
            "example": "203.0.113.42"
          },
          {
            "name": "game_id",
            "in": "query",
            "required": false,
            "description": "Kecocokan persis pada `game_id` yang dipromosikan.",
            "schema": {
              "type": "string"
            },
            "example": "poker-holdem-01"
          },
          {
            "name": "round_id",
            "in": "query",
            "required": false,
            "description": "Kecocokan persis pada `round_id` yang dipromosikan.",
            "schema": {
              "type": "string"
            },
            "example": "round-88231"
          },
          {
            "name": "affiliate_code",
            "in": "query",
            "required": false,
            "description": "Kecocokan persis pada `affiliate_code` yang dipromosikan.",
            "schema": {
              "type": "string"
            },
            "example": "aff-summer"
          },
          {
            "name": "payment_reference_id",
            "in": "query",
            "required": false,
            "description": "Kecocokan persis pada referensi pembayaran (dari `transaction_context.payment_reference_id` atau `payload.payment_reference_id`).",
            "schema": {
              "type": "string"
            },
            "example": "dep_735"
          },
          {
            "name": "counterparty_vendor_data",
            "in": "query",
            "required": false,
            "description": "Kecocokan persis pada `counterparty_vendor_data` yang dipromosikan.",
            "schema": {
              "type": "string"
            },
            "example": "user-77"
          },
          {
            "name": "matched_only",
            "in": "query",
            "required": false,
            "description": "`true` (juga `1` atau `yes`, tidak peka huruf besar/kecil) hanya mengembalikan event yang cocok dengan setidaknya satu aturan (`rules_matched_count` di atas 0). Nilai lainnya akan diabaikan.",
            "schema": {
              "type": "boolean",
              "default": false
            },
            "example": true
          },
          {
            "name": "occurred_from",
            "in": "query",
            "required": false,
            "description": "Hanya event dengan `occurred_at` pada atau setelah waktu ini (inklusif). Kirimkan nilai ISO 8601: `2026-10-01T00:00:00Z`, offset eksplisit dengan tanda `+` yang di-percent-encode (`2026-10-01T02:00:00%2B02:00`; tanda `+` tanpa encoding akan didekodekan sebagai spasi dan nilainya tidak dapat lagi di-parse), atau tanggal saja (`2026-10-01`), yang berarti pukul 00:00:00 UTC pada hari tersebut. Nilai tanpa offset dibaca sebagai UTC. Nilai dalam format lainnya tidak diterima.",
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "example": "2026-10-01T00:00:00Z"
          },
          {
            "name": "occurred_to",
            "in": "query",
            "required": false,
            "description": "Hanya event dengan `occurred_at` pada atau sebelum waktu ini (inklusif). Tanggal saja berarti awal hari tersebut, sehingga `occurred_to=2026-10-15` tidak menyertakan sisa hari 15 Oktober; kirimkan `2026-10-15T23:59:59Z` untuk menyertakannya. Kirimkan nilai ISO 8601: `2026-10-01T00:00:00Z`, offset eksplisit dengan tanda `+` yang di-percent-encode (`2026-10-01T02:00:00%2B02:00`; tanda `+` tanpa encoding akan didekodekan sebagai spasi dan nilainya tidak dapat lagi di-parse), atau tanggal saja (`2026-10-01`), yang berarti pukul 00:00:00 UTC pada hari tersebut. Nilai tanpa offset dibaca sebagai UTC. Nilai dalam format lainnya tidak diterima.",
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "example": "2026-10-17T23:59:59Z"
          },
          {
            "name": "search",
            "in": "query",
            "required": false,
            "description": "Pencocokan substring yang tidak peka huruf besar/kecil pada `event_id`, `action_type`, `subject_vendor_data`, atau `counterparty_vendor_data`.",
            "schema": {
              "type": "string"
            },
            "example": "chargeback"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/events/?event_category=payment&event_category=dispute&matched_only=true&occurred_from=2026-10-01T00:00:00Z&limit=50' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nfor item in client.monitoring_events.list():\n    print(item)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nfor await (const item of didit.monitoringEvents.list()) {\n  console.log(item);\n}"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\niter := client.MonitoringEvents.ListAutoPaging(ctx, didit.MonitoringEventsListParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nfor (var item : client.monitoringEvents().list()) {\n    System.out.println(item);\n}"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\nforeach ($didit->monitoringEvents->list() as $item) {\n    print_r($item->toArray());\n}"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.monitoring_events.list.auto_paging_each do |item|\n  puts item.to_h\nend"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.MonitoringEvents.ListAsync())\n{\n    Console.WriteLine(JsonSerializer.Serialize(item));\n}"
          }
        ],
        "responses": {
          "200": {
            "description": "Satu halaman ringkasan event.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MonitoringEventPage"
                },
                "examples": {
                  "Payment and dispute events": {
                    "value": {
                      "count": 2,
                      "next": null,
                      "previous": null,
                      "results": [
                        {
                          "event_uuid": "11111111-2222-3333-4444-555555555555",
                          "event_id": "chargeback-2026-10-16-000318",
                          "event_category": "dispute",
                          "action_type": "chargeback_opened",
                          "occurred_at": "2026-10-16T14:02:11Z",
                          "received_at": "2026-10-16T14:02:12.418230Z",
                          "status": "IN_REVIEW",
                          "score": 60,
                          "subject_vendor_data": "user-42",
                          "subject_entity_type": "individual",
                          "subject_uuid": "66666666-7777-8888-9999-000000000000",
                          "counterparty_vendor_data": null,
                          "session_id": null,
                          "device_fingerprint": null,
                          "ip_address": null,
                          "ip_country": null,
                          "amount": "250.000000000000000000",
                          "currency": "EUR",
                          "game_id": null,
                          "round_id": null,
                          "bonus_id": null,
                          "affiliate_code": null,
                          "payment_reference_id": "dep_735",
                          "retention_class": "monetary_or_compliance",
                          "rules_matched_count": 1,
                          "correlation_pending": false,
                          "is_droppable": false
                        },
                        {
                          "event_uuid": "22222222-3333-4444-5555-666666666666",
                          "event_id": "login-2026-10-15-000912",
                          "event_category": "auth",
                          "action_type": "login",
                          "occurred_at": "2026-10-15T08:30:00.120000Z",
                          "received_at": "2026-10-15T08:30:00.734512Z",
                          "status": "ACCEPTED",
                          "score": 0,
                          "subject_vendor_data": "user-42",
                          "subject_entity_type": "individual",
                          "subject_uuid": "66666666-7777-8888-9999-000000000000",
                          "counterparty_vendor_data": null,
                          "session_id": "web-session-abc",
                          "device_fingerprint": "fp-a8c1",
                          "ip_address": "203.0.113.42",
                          "ip_country": "ES",
                          "amount": null,
                          "currency": null,
                          "game_id": null,
                          "round_id": null,
                          "bonus_id": null,
                          "affiliate_code": null,
                          "payment_reference_id": null,
                          "retention_class": "standard",
                          "rules_matched_count": 0,
                          "correlation_pending": false,
                          "is_droppable": true
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "`limit` atau `offset` lebih besar dari 1000000. Bagian body adalah array JSON dengan satu pesan. Nilai `limit` yang non-numerik atau non-positif dialihkan kembali ke default 50 daripada gagal.",
            "content": {
              "application/json": {
                "examples": {
                  "limit too large": {
                    "summary": "limit di atas 1000000",
                    "value": [
                      "limit must not exceed 1000000."
                    ]
                  },
                  "offset too large": {
                    "summary": "offset di atas 1000000",
                    "value": [
                      "offset must not exceed 1000000."
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Kunci API dengan cakupan terbatas telah kedaluwarsa. Hanya kunci yang kedaluwarsa yang menerima `401`; kunci yang hilang atau tidak valid menerima `403`.",
            "content": {
              "application/json": {
                "examples": {
                  "Expired key": {
                    "value": {
                      "detail": "This API key has expired."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "`x-api-key` tidak ada (kunci yang salah, dicabut, atau kedaluwarsa menghasilkan `401`), kunci dengan pembatasan cakupan tanpa `transactions: read`, kunci yang dibatasi pada alur kerja tertentu atau pada sesi yang disetujui (kunci semacam itu tidak pernah mengakses data pemantauan transaksi), atau permintaan dari luar allowlist IP milik kunci tersebut.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing or invalid API key": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Scoped key without access": {
                    "value": {
                      "detail": "This API key has no read access to transactions."
                    }
                  },
                  "Key limited to workflows or approved sessions": {
                    "value": {
                      "detail": "This API key only reaches sessions inside its workflow or status limits, so it can't use this endpoint."
                    }
                  },
                  "IP not allowed": {
                    "value": {
                      "detail": "This API key can't be used from this IP address."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Batas laju terlampaui: permintaan `GET` berbagi anggaran sebanyak 600 permintaan per menit per kunci API. Tunggu `Retry-After` detik, lalu coba lagi.",
            "headers": {
              "Retry-After": {
                "description": "Detik untuk menunggu sebelum mencoba lagi.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "example": 30
                }
              }
            },
            "content": {
              "application/json": {
                "examples": {
                  "Throttled": {
                    "value": {
                      "detail": "GET request rate limit exceeded. You can make up to 600 requests per minute."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      },
      "post": {
        "summary": "Buat event pemantauan",
        "description": "Kirim satu event nonmoneter (login, sesi, gameplay, bonus, afiliasi, pembayaran, sengketa, keamanan, perjudian yang bertanggung jawab, atau kustom) dari backend Anda. Event divalidasi terhadap kontrak kategorinya, disimpan, diperkaya dengan informasi IP satu kali per alamat publik unik, dan dievaluasi oleh aturan event real-time Anda sebelum respons dikembalikan; aturan lintas-subjek dan jendela waktu yang panjang berjalan secara asinkron (`correlation_pending: true`), dan dalam aplikasi sandbox tidak ada aturan yang berjalan. `event_id` adalah kunci idempotensi: `event_id` yang sama dengan `event_category`, `action_type`, `occurred_at`, `subject.vendor_data`, dan `payload` yang sama mengembalikan `200` dengan `idempotent_replay: true` dan hasil yang disimpan (kolom lain dalam envelope tidak dibandingkan), sedangkan nilai yang berbeda mengembalikan `409`. Penyerapan event bersifat opt-in per aplikasi: hingga diaktifkan, endpoint ini mengembalikan `403` dengan `code: event_monitoring_disabled` dan tidak menyimpan apa pun. Kunci API dengan cakupan memerlukan `transactions: write`. Lihat [Penyerapan event](https://docs.didit.me/id/transaction-monitoring/events) dan [Aturan pada event](https://docs.didit.me/id/transaction-monitoring/event-rules); untuk mengirim event dari browser atau aplikasi, gunakan [Pengiriman event SDK](https://docs.didit.me/id/transaction-monitoring/sdk-event-submission).",
        "operationId": "create_monitoring_event",
        "x-didit-sdk": {
          "resource": "monitoring_events",
          "method": "create",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Monitoring Events"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MonitoringEventCreateRequest"
              },
              "examples": {
                "Login": {
                  "value": {
                    "event_id": "login-2026-10-17-000001",
                    "event_category": "auth",
                    "action_type": "login",
                    "occurred_at": "2026-10-17T09:15:02.481Z",
                    "time_zone": "Europe/Madrid",
                    "subject": {
                      "vendor_data": "user-42",
                      "entity_type": "individual"
                    },
                    "session": {
                      "session_id": "web-session-abc",
                      "sequence": 142
                    },
                    "device_context": {
                      "fingerprint": "fp-a8c1",
                      "network_context": {
                        "ip_address": "203.0.113.42"
                      }
                    },
                    "payload": {
                      "method": "password"
                    },
                    "custom_values": {
                      "vip_tier": "gold"
                    }
                  }
                },
                "Deposit completed": {
                  "value": {
                    "event_id": "deposit-2026-10-17-000002",
                    "event_category": "payment",
                    "action_type": "deposit_completed",
                    "occurred_at": "2026-10-17T09:16:40Z",
                    "subject": {
                      "vendor_data": "user-42"
                    },
                    "transaction_context": {
                      "amount": "100.00",
                      "currency": "EUR",
                      "direction": "inbound",
                      "payment_reference_id": "dep_736"
                    },
                    "payload": {
                      "payment_method": "card",
                      "status": "completed"
                    }
                  }
                },
                "Chargeback opened": {
                  "value": {
                    "event_id": "chargeback-2026-10-16-000318",
                    "event_category": "dispute",
                    "action_type": "chargeback_opened",
                    "occurred_at": "2026-10-16T14:02:11Z",
                    "subject": {
                      "vendor_data": "user-42"
                    },
                    "payload": {
                      "payment_reference_id": "dep_735",
                      "chargeback_id": "cb_5521",
                      "amount": "250.00",
                      "currency": "EUR",
                      "reason_code": "fraud"
                    }
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://verification.didit.me/v3/events/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"event_id\": \"login-2026-10-17-000001\",\n    \"event_category\": \"auth\",\n    \"action_type\": \"login\",\n    \"occurred_at\": \"2026-10-17T09:15:02.481Z\",\n    \"subject\": {\"vendor_data\": \"user-42\", \"entity_type\": \"individual\"},\n    \"session\": {\"session_id\": \"web-session-abc\", \"sequence\": 142},\n    \"device_context\": {\n      \"fingerprint\": \"fp-a8c1\",\n      \"network_context\": {\"ip_address\": \"203.0.113.42\"}\n    },\n    \"payload\": {\"method\": \"password\"}\n  }'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.monitoring_events.create(\n    event_id=\"login-2026-10-17-000001\",\n    event_category=\"auth\",\n    action_type=\"login\",\n    occurred_at=\"2026-10-17T09:15:02.481Z\",\n    time_zone=\"Europe/Madrid\",\n    subject={\n        \"vendor_data\": \"user-42\",\n        \"entity_type\": \"individual\",\n    },\n    session={\n        \"session_id\": \"web-session-abc\",\n        \"sequence\": 142,\n    },\n    device_context={\n        \"fingerprint\": \"fp-a8c1\",\n        \"network_context\": {\n            \"ip_address\": \"203.0.113.42\",\n        },\n    },\n    payload={\"method\": \"password\"},\n    custom_values={\"vip_tier\": \"gold\"},\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.monitoringEvents.create({\n  event_id: \"login-2026-10-17-000001\",\n  event_category: \"auth\",\n  action_type: \"login\",\n  occurred_at: \"2026-10-17T09:15:02.481Z\",\n  time_zone: \"Europe/Madrid\",\n  subject: {\n    vendor_data: \"user-42\",\n    entity_type: \"individual\",\n  },\n  session: {\n    session_id: \"web-session-abc\",\n    sequence: 142,\n  },\n  device_context: {\n    fingerprint: \"fp-a8c1\",\n    network_context: {\n      ip_address: \"203.0.113.42\",\n    },\n  },\n  payload: { method: \"password\" },\n  custom_values: { vip_tier: \"gold\" },\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.MonitoringEvents.Create(ctx, didit.MonitoringEventCreateRequest{\n\tEventID:       \"login-2026-10-17-000001\",\n\tEventCategory: \"auth\",\n\tActionType:    \"login\",\n\tOccurredAt:    time.Date(2026, 10, 17, 9, 15, 2, 0, time.UTC),\n\tTimeZone:      didit.String(\"Europe/Madrid\"),\n\tSubject: didit.MonitoringEventCreateRequestSubject{\n\t\tVendorData: \"user-42\",\n\t\tEntityType: didit.String(\"individual\"),\n\t},\n\tSession: didit.Some(didit.MonitoringEventCreateRequestSession{\n\t\tSessionID: didit.String(\"web-session-abc\"),\n\t\tSequence:  didit.Int(142),\n\t}),\n\tDeviceContext: didit.Some(didit.MonitoringEventCreateRequestDeviceContext{\n\t\tFingerprint: didit.String(\"fp-a8c1\"),\n\t\tNetworkContext: didit.Some(didit.MonitoringEventCreateRequestDeviceContextNetworkContext{\n\t\t\tIPAddress: didit.String(\"203.0.113.42\"),\n\t\t}),\n\t}),\n\tPayload:      didit.Some(map[string]any{\"method\": \"password\"}),\n\tCustomValues: didit.Some(map[string]any{\"vip_tier\": \"gold\"}),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.time.OffsetDateTime;\nimport java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.MonitoringEventCreateRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.monitoringEvents().create(MonitoringEventCreateRequest.builder()\n        .eventId(\"login-2026-10-17-000001\")\n        .eventCategory(MonitoringEventCreateRequest.EventCategory.of(\"auth\"))\n        .actionType(\"login\")\n        .occurredAt(OffsetDateTime.parse(\"2026-10-17T09:15:02.481Z\"))\n        .timeZone(\"Europe/Madrid\")\n        .subject(MonitoringEventCreateRequest.Subject.builder()\n                .vendorData(\"user-42\")\n                .entityType(\"individual\")\n                .build())\n        .session(MonitoringEventCreateRequest.Session.builder()\n                .sessionId(\"web-session-abc\")\n                .sequence(142L)\n                .build())\n        .deviceContext(MonitoringEventCreateRequest.DeviceContext.builder()\n                .fingerprint(\"fp-a8c1\")\n                .networkContext(MonitoringEventCreateRequest.DeviceContext.NetworkContext.builder()\n                        .ipAddress(\"203.0.113.42\")\n                        .build())\n                .build())\n        .payload(Map.of(\"method\", \"password\"))\n        .customValues(Map.of(\"vip_tier\", MonitoringEventCreateRequest.CustomValuesValue.ofString(\"gold\")))\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->monitoringEvents->create([\n    'event_id' => 'login-2026-10-17-000001',\n    'event_category' => 'auth',\n    'action_type' => 'login',\n    'occurred_at' => '2026-10-17T09:15:02.481Z',\n    'time_zone' => 'Europe/Madrid',\n    'subject' => [\n        'vendor_data' => 'user-42',\n        'entity_type' => 'individual',\n    ],\n    'session' => [\n        'session_id' => 'web-session-abc',\n        'sequence' => 142,\n    ],\n    'device_context' => [\n        'fingerprint' => 'fp-a8c1',\n        'network_context' => [\n            'ip_address' => '203.0.113.42',\n        ],\n    ],\n    'payload' => ['method' => 'password'],\n    'custom_values' => ['vip_tier' => 'gold'],\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.monitoring_events.create(\n  event_id: \"login-2026-10-17-000001\",\n  event_category: \"auth\",\n  action_type: \"login\",\n  occurred_at: \"2026-10-17T09:15:02.481Z\",\n  time_zone: \"Europe/Madrid\",\n  subject: {\n    vendor_data: \"user-42\",\n    entity_type: \"individual\",\n  },\n  session: {\n    session_id: \"web-session-abc\",\n    sequence: 142,\n  },\n  device_context: {\n    fingerprint: \"fp-a8c1\",\n    network_context: {\n      ip_address: \"203.0.113.42\",\n    },\n  },\n  payload: { method: \"password\" },\n  custom_values: { vip_tier: \"gold\" }\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.MonitoringEvents.CreateAsync(new MonitoringEventCreateRequest\n{\n    EventId = \"login-2026-10-17-000001\",\n    EventCategory = \"auth\",\n    ActionType = \"login\",\n    OccurredAt = DateTimeOffset.Parse(\"2026-10-17T09:15:02.481Z\"),\n    TimeZone = \"Europe/Madrid\",\n    Subject = new()\n    {\n        VendorData = \"user-42\",\n        EntityType = \"individual\",\n    },\n    Session = new MonitoringEventCreateRequestSession\n    {\n        SessionId = \"web-session-abc\",\n        Sequence = 142,\n    },\n    DeviceContext = new MonitoringEventCreateRequestDeviceContext\n    {\n        Fingerprint = \"fp-a8c1\",\n        NetworkContext = new MonitoringEventCreateRequestDeviceContextNetworkContext\n        {\n            IpAddress = \"203.0.113.42\",\n        },\n    },\n    Payload = new Dictionary<string, object> { [\"method\"] = \"password\" },\n    CustomValues = new Dictionary<string, object> { [\"vip_tier\"] = \"gold\" },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "201": {
            "description": "Event telah disimpan dan dievaluasi.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MonitoringEventIngestResult"
                },
                "examples": {
                  "Stored, no rule matched": {
                    "value": {
                      "event_uuid": "33333333-4444-5555-6666-777777777777",
                      "event_id": "login-2026-10-17-000001",
                      "status": "ACCEPTED",
                      "score": 0,
                      "rules_evaluated_count": 6,
                      "rules_matched_count": 0,
                      "correlation_pending": false,
                      "retention_class": "standard",
                      "expires_at": "2026-11-16T09:15:02.481000Z",
                      "idempotent_replay": false,
                      "rule_matches": []
                    }
                  },
                  "Rule matched, async rule pending": {
                    "value": {
                      "event_uuid": "33333333-4444-5555-6666-777777777777",
                      "event_id": "login-2026-10-17-000001",
                      "status": "IN_REVIEW",
                      "score": 40,
                      "rules_evaluated_count": 6,
                      "rules_matched_count": 1,
                      "correlation_pending": true,
                      "retention_class": "risk_relevant",
                      "expires_at": "2027-01-15T09:15:02.481000Z",
                      "idempotent_replay": false,
                      "rule_matches": [
                        {
                          "rule_id": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee",
                          "library_key": null,
                          "mode": "ACTIVE",
                          "is_async": false
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "200": {
            "description": "Pemutaran ulang idempoten: event dengan `event_id` ini dan konten yang sama sudah tersimpan. Tidak ada yang disimpan atau dievaluasi ulang; body menjelaskan event yang tersimpan.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MonitoringEventIngestResult"
                },
                "examples": {
                  "Replay": {
                    "value": {
                      "event_uuid": "33333333-4444-5555-6666-777777777777",
                      "event_id": "login-2026-10-17-000001",
                      "status": "ACCEPTED",
                      "score": 0,
                      "rules_evaluated_count": 6,
                      "rules_matched_count": 0,
                      "correlation_pending": false,
                      "retention_class": "standard",
                      "expires_at": "2026-11-16T09:15:02.481000Z",
                      "idempotent_replay": true,
                      "rule_matches": []
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validasi gagal. Body diindeks berdasarkan kolom; kolom bersarang berupa objek bersarang. Tidak ada yang disimpan.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing fields": {
                    "value": {
                      "event_id": [
                        "This field is required."
                      ],
                      "subject": [
                        "This field is required."
                      ]
                    }
                  },
                  "Unknown category": {
                    "value": {
                      "event_category": [
                        "\"login\" is not a valid choice."
                      ]
                    }
                  },
                  "occurred_at too old": {
                    "value": {
                      "occurred_at": [
                        "occurred_at is more than 7 days in the past. Use the batch import lane for backfills."
                      ]
                    }
                  },
                  "occurred_at in the future": {
                    "value": {
                      "occurred_at": [
                        "occurred_at is more than 5 minutes in the future."
                      ]
                    }
                  },
                  "Missing subject vendor_data": {
                    "value": {
                      "subject": {
                        "vendor_data": [
                          "This field is required."
                        ]
                      }
                    }
                  },
                  "Missing required payload keys": {
                    "value": {
                      "payload": [
                        "payment.deposit_completed requires: payment_method, status."
                      ]
                    }
                  },
                  "Missing one-of payload key": {
                    "value": {
                      "payload": [
                        "dispute.chargeback_opened requires one of: dispute_id, chargeback_id."
                      ]
                    }
                  },
                  "Security change without changed_field": {
                    "value": {
                      "payload": [
                        "security.*_changed requires 'changed_field'."
                      ]
                    }
                  },
                  "Payload too large": {
                    "value": {
                      "payload": [
                        "payload exceeds 16384 bytes. Summarise telemetry client-side."
                      ]
                    }
                  },
                  "Too many custom_values": {
                    "value": {
                      "custom_values": [
                        "custom_values accepts at most 100 keys."
                      ]
                    }
                  },
                  "Nested custom value": {
                    "value": {
                      "custom_values": [
                        "custom_values['limits'] must be a scalar - rule conditions cannot address nested values."
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Kunci API dengan cakupan terbatas telah kedaluwarsa. Hanya kunci yang kedaluwarsa yang menerima `401`; kunci yang hilang atau tidak valid menerima `403`.",
            "content": {
              "application/json": {
                "examples": {
                  "Expired key": {
                    "value": {
                      "detail": "This API key has expired."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "`x-api-key` tidak ada (kunci yang salah, dicabut, atau kedaluwarsa menghasilkan `401`), kunci dengan pembatasan cakupan tanpa `transactions: write`, kunci yang dibatasi pada alur kerja tertentu atau pada sesi yang disetujui (kunci semacam itu tidak pernah mengakses data pemantauan transaksi), atau permintaan dari luar allowlist IP milik kunci tersebut. Juga dikembalikan dengan `code: event_monitoring_disabled` saat penyerapan event dinonaktifkan untuk aplikasi; tidak ada yang disimpan dalam kasus tersebut, dan pemeriksaan berjalan sebelum body divalidasi.",
            "content": {
              "application/json": {
                "examples": {
                  "Event monitoring disabled": {
                    "value": {
                      "detail": "Event monitoring is not enabled for this application. Turn on event ingestion in the transaction monitoring settings before submitting events.",
                      "code": "event_monitoring_disabled"
                    }
                  },
                  "Missing or invalid API key": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Scoped key without access": {
                    "value": {
                      "detail": "This API key has no write access to transactions."
                    }
                  },
                  "Key limited to workflows or approved sessions": {
                    "value": {
                      "detail": "This API key only reaches sessions inside its workflow or status limits, so it can't use this endpoint."
                    }
                  },
                  "IP not allowed": {
                    "value": {
                      "detail": "This API key can't be used from this IP address."
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "`event_id` sudah digunakan untuk event dengan konten berbeda (kategori, jenis tindakan, `occurred_at`, `vendor_data` subjek, atau payload). Kirim event dengan `event_id` baru.",
            "content": {
              "application/json": {
                "examples": {
                  "event_id reused": {
                    "value": {
                      "event_id": "event_id 'login-2026-10-17-000001' already exists with a different payload."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Batas laju terlampaui: pembuatan transaksi dan penyerapan event (`POST /v3/transactions/`, `POST /v3/events/`, `POST /v3/events/batch/`) berbagi anggaran sebanyak 600 permintaan per menit per kunci API, terpisah dari anggaran 300 permintaan yang digunakan bersama oleh semua permintaan tulis lainnya. Tunggu `Retry-After` detik, lalu coba lagi.",
            "headers": {
              "Retry-After": {
                "description": "Detik yang harus ditunggu sebelum mencoba lagi, dibulatkan ke atas agar percobaan berikutnya berada di jendela berikutnya.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "example": 30
                }
              }
            },
            "content": {
              "application/json": {
                "examples": {
                  "Throttled": {
                    "value": {
                      "detail": "Ingestion rate limit exceeded. You can make up to 600 requests per minute."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/events/batch/": {
      "post": {
        "summary": "Buat event pemantauan secara batch",
        "description": "Kirim 1 hingga 500 event dalam satu permintaan, masing-masing dalam format pembungkus yang sama seperti `POST /v3/events/`. Setiap item divalidasi, disimpan, dan dievaluasi secara mandiri serta mendapatkan hasilnya sendiri (`accepted`, `replayed`, atau `rejected`), sehingga satu event yang salah format tidak pernah membatalkan yang lain: respons bernilai `201` jika tidak ada item yang ditolak dan `207` jika setidaknya ada satu yang ditolak, dan keduanya berarti permintaan telah diproses. Kirim `{\"events\": [...]}`; array JSON berisi event tanpa pembungkus juga diterima. Ingesti event harus diaktifkan untuk aplikasi, jika tidak, seluruh permintaan mengembalikan `403` dengan `code: event_monitoring_disabled` dan tidak ada yang disimpan. Kunci API scoped memerlukan `transactions: write`. Lihat [Batch](https://docs.didit.me/id/transaction-monitoring/events#batch).",
        "operationId": "create_monitoring_events_batch",
        "x-didit-sdk": {
          "resource": "monitoring_events",
          "method": "create_batch",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Monitoring Events"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "events"
                ],
                "properties": {
                  "events": {
                    "type": "array",
                    "minItems": 1,
                    "maxItems": 500,
                    "description": "1 hingga 500 event. Setiap item mengikuti `MonitoringEventCreateRequest`, termasuk rentang 7 hari ke belakang dan 5 menit ke depan pada `occurred_at`.",
                    "items": {
                      "$ref": "#/components/schemas/MonitoringEventCreateRequest"
                    }
                  }
                }
              },
              "example": {
                "events": [
                  {
                    "event_id": "login-2026-10-17-000001",
                    "event_category": "auth",
                    "action_type": "login",
                    "occurred_at": "2026-10-17T09:15:02.481Z",
                    "subject": {
                      "vendor_data": "user-42"
                    }
                  },
                  {
                    "event_id": "deposit-2026-10-17-000002",
                    "event_category": "payment",
                    "action_type": "deposit_completed",
                    "occurred_at": "2026-10-17T09:16:40Z",
                    "subject": {
                      "vendor_data": "user-42"
                    },
                    "transaction_context": {
                      "amount": "100.00",
                      "currency": "EUR",
                      "payment_reference_id": "dep_736"
                    },
                    "payload": {
                      "payment_method": "card",
                      "status": "completed"
                    }
                  }
                ]
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://verification.didit.me/v3/events/batch/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"events\": [\n      {\"event_id\": \"login-2026-10-17-000001\", \"event_category\": \"auth\", \"action_type\": \"login\",\n       \"occurred_at\": \"2026-10-17T09:15:02.481Z\", \"subject\": {\"vendor_data\": \"user-42\"}},\n      {\"event_id\": \"deposit-2026-10-17-000002\", \"event_category\": \"payment\", \"action_type\": \"deposit_completed\",\n       \"occurred_at\": \"2026-10-17T09:16:40.000Z\", \"subject\": {\"vendor_data\": \"user-42\"},\n       \"transaction_context\": {\"amount\": \"100.00\", \"currency\": \"EUR\", \"payment_reference_id\": \"dep_736\"},\n       \"payload\": {\"payment_method\": \"card\", \"status\": \"completed\"}}\n    ]\n  }'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.monitoring_events.create_batch(\n    events=[{\n        \"event_id\": \"login-2026-10-17-000001\",\n        \"event_category\": \"auth\",\n        \"action_type\": \"login\",\n        \"occurred_at\": \"2026-10-17T09:15:02.481Z\",\n        \"subject\": {\n            \"vendor_data\": \"user-42\",\n        },\n    }, {\n        \"event_id\": \"deposit-2026-10-17-000002\",\n        \"event_category\": \"payment\",\n        \"action_type\": \"deposit_completed\",\n        \"occurred_at\": \"2026-10-17T09:16:40Z\",\n        \"subject\": {\n            \"vendor_data\": \"user-42\",\n        },\n        \"transaction_context\": {\n            \"amount\": \"100.00\",\n            \"currency\": \"EUR\",\n            \"payment_reference_id\": \"dep_736\",\n        },\n        \"payload\": {\"payment_method\": \"card\", \"status\": \"completed\"},\n    }],\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.monitoringEvents.createBatch({\n  events: [{\n    event_id: \"login-2026-10-17-000001\",\n    event_category: \"auth\",\n    action_type: \"login\",\n    occurred_at: \"2026-10-17T09:15:02.481Z\",\n    subject: {\n      vendor_data: \"user-42\",\n    },\n  }, {\n    event_id: \"deposit-2026-10-17-000002\",\n    event_category: \"payment\",\n    action_type: \"deposit_completed\",\n    occurred_at: \"2026-10-17T09:16:40Z\",\n    subject: {\n      vendor_data: \"user-42\",\n    },\n    transaction_context: {\n      amount: \"100.00\",\n      currency: \"EUR\",\n      payment_reference_id: \"dep_736\",\n    },\n    payload: { payment_method: \"card\", status: \"completed\" },\n  }],\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.MonitoringEvents.CreateBatch(ctx, didit.MonitoringEventsCreateBatchParams{\n\tEvents: []didit.MonitoringEventCreateRequest{{\n\t\tEventID:       \"login-2026-10-17-000001\",\n\t\tEventCategory: \"auth\",\n\t\tActionType:    \"login\",\n\t\tOccurredAt:    time.Date(2026, 10, 17, 9, 15, 2, 0, time.UTC),\n\t\tSubject: didit.MonitoringEventCreateRequestSubject{\n\t\t\tVendorData: \"user-42\",\n\t\t},\n\t}, {\n\t\tEventID:       \"deposit-2026-10-17-000002\",\n\t\tEventCategory: \"payment\",\n\t\tActionType:    \"deposit_completed\",\n\t\tOccurredAt:    time.Date(2026, 10, 17, 9, 16, 40, 0, time.UTC),\n\t\tSubject: didit.MonitoringEventCreateRequestSubject{\n\t\t\tVendorData: \"user-42\",\n\t\t},\n\t\tTransactionContext: didit.Some(didit.MonitoringEventCreateRequestTransactionContext{\n\t\t\tAmount:             didit.String(\"100.00\"),\n\t\t\tCurrency:           didit.String(\"EUR\"),\n\t\t\tPaymentReferenceID: didit.String(\"dep_736\"),\n\t\t}),\n\t\tPayload: didit.Some(map[string]any{\"payment_method\": \"card\", \"status\": \"completed\"}),\n\t}},\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.time.OffsetDateTime;\nimport java.util.List;\nimport java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.MonitoringEventCreateRequest;\nimport me.didit.types.MonitoringEventsCreateBatchParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.monitoringEvents().createBatch(MonitoringEventsCreateBatchParams.builder()\n        .events(List.of(\n                MonitoringEventCreateRequest.builder()\n                        .eventId(\"login-2026-10-17-000001\")\n                        .eventCategory(MonitoringEventCreateRequest.EventCategory.of(\"auth\"))\n                        .actionType(\"login\")\n                        .occurredAt(OffsetDateTime.parse(\"2026-10-17T09:15:02.481Z\"))\n                        .subject(MonitoringEventCreateRequest.Subject.builder()\n                                .vendorData(\"user-42\")\n                                .build())\n                        .build(),\n                MonitoringEventCreateRequest.builder()\n                        .eventId(\"deposit-2026-10-17-000002\")\n                        .eventCategory(MonitoringEventCreateRequest.EventCategory.of(\"payment\"))\n                        .actionType(\"deposit_completed\")\n                        .occurredAt(OffsetDateTime.parse(\"2026-10-17T09:16:40Z\"))\n                        .subject(MonitoringEventCreateRequest.Subject.builder()\n                                .vendorData(\"user-42\")\n                                .build())\n                        .transactionContext(MonitoringEventCreateRequest.TransactionContext.builder()\n                                .amount(\"100.00\")\n                                .currency(\"EUR\")\n                                .paymentReferenceId(\"dep_736\")\n                                .build())\n                        .payload(Map.of(\"payment_method\", \"card\", \"status\", \"completed\"))\n                        .build()))\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->monitoringEvents->createBatch([\n    'events' => [[\n        'event_id' => 'login-2026-10-17-000001',\n        'event_category' => 'auth',\n        'action_type' => 'login',\n        'occurred_at' => '2026-10-17T09:15:02.481Z',\n        'subject' => [\n            'vendor_data' => 'user-42',\n        ],\n    ], [\n        'event_id' => 'deposit-2026-10-17-000002',\n        'event_category' => 'payment',\n        'action_type' => 'deposit_completed',\n        'occurred_at' => '2026-10-17T09:16:40Z',\n        'subject' => [\n            'vendor_data' => 'user-42',\n        ],\n        'transaction_context' => [\n            'amount' => '100.00',\n            'currency' => 'EUR',\n            'payment_reference_id' => 'dep_736',\n        ],\n        'payload' => ['payment_method' => 'card', 'status' => 'completed'],\n    ]],\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.monitoring_events.create_batch(\n  events: [{\n    event_id: \"login-2026-10-17-000001\",\n    event_category: \"auth\",\n    action_type: \"login\",\n    occurred_at: \"2026-10-17T09:15:02.481Z\",\n    subject: {\n      vendor_data: \"user-42\",\n    },\n  }, {\n    event_id: \"deposit-2026-10-17-000002\",\n    event_category: \"payment\",\n    action_type: \"deposit_completed\",\n    occurred_at: \"2026-10-17T09:16:40Z\",\n    subject: {\n      vendor_data: \"user-42\",\n    },\n    transaction_context: {\n      amount: \"100.00\",\n      currency: \"EUR\",\n      payment_reference_id: \"dep_736\",\n    },\n    payload: { payment_method: \"card\", status: \"completed\" },\n  }]\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.MonitoringEvents.CreateBatchAsync(new MonitoringEventsCreateBatchParams\n{\n    Events = new MonitoringEventCreateRequest[]\n    {\n        new()\n        {\n            EventId = \"login-2026-10-17-000001\",\n            EventCategory = \"auth\",\n            ActionType = \"login\",\n            OccurredAt = DateTimeOffset.Parse(\"2026-10-17T09:15:02.481Z\"),\n            Subject = new()\n            {\n                VendorData = \"user-42\",\n            },\n        },\n        new()\n        {\n            EventId = \"deposit-2026-10-17-000002\",\n            EventCategory = \"payment\",\n            ActionType = \"deposit_completed\",\n            OccurredAt = DateTimeOffset.Parse(\"2026-10-17T09:16:40Z\"),\n            Subject = new()\n            {\n                VendorData = \"user-42\",\n            },\n            TransactionContext = new MonitoringEventCreateRequestTransactionContext\n            {\n                Amount = \"100.00\",\n                Currency = \"EUR\",\n                PaymentReferenceId = \"dep_736\",\n            },\n            Payload = new Dictionary<string, object> { [\"payment_method\"] = \"card\", [\"status\"] = \"completed\" },\n        },\n    },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "201": {
            "description": "Tidak ada item yang ditolak: setiap item berstatus `accepted` atau `replayed`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "accepted_count",
                    "replayed_count",
                    "rejected_count",
                    "results"
                  ],
                  "properties": {
                    "accepted_count": {
                      "type": "integer",
                      "minimum": 0,
                      "description": "Item disimpan dan dievaluasi."
                    },
                    "replayed_count": {
                      "type": "integer",
                      "minimum": 0,
                      "description": "Item yang sudah tersimpan dengan konten yang sama."
                    },
                    "rejected_count": {
                      "type": "integer",
                      "minimum": 0,
                      "description": "Item tidak disimpan."
                    },
                    "results": {
                      "type": "array",
                      "description": "Satu entri per item, sesuai urutan permintaan.",
                      "items": {
                        "type": "object",
                        "description": "Hasil dari satu item. Item yang diterima dan diputar ulang juga memuat setiap kolom dari `MonitoringEventIngestResult`; item yang ditolak justru memuat `event_id` dan `errors`.",
                        "required": [
                          "index",
                          "outcome"
                        ],
                        "properties": {
                          "index": {
                            "type": "integer",
                            "minimum": 0,
                            "description": "Posisi item dalam array `events` Anda."
                          },
                          "outcome": {
                            "type": "string",
                            "enum": [
                              "accepted",
                              "replayed",
                              "rejected"
                            ],
                            "description": "`accepted`: disimpan dan dievaluasi. `replayed`: sudah disimpan dengan konten yang sama. `rejected`: tidak disimpan; lihat `errors`."
                          },
                          "event_id": {
                            "type": "string",
                            "nullable": true,
                            "description": "`event_id` Anda. Pada item yang ditolak oleh validasi, nilai ini dibaca dari kunci snake_case `event_id` milik item tersebut, sehingga bernilai null ketika item tersebut menghilangkannya atau mengirimkan alias `eventId`."
                          },
                          "errors": {
                            "type": "object",
                            "additionalProperties": true,
                            "description": "Hanya item yang ditolak. Kesalahan validasi dikelompokkan berdasarkan kolom, dalam format yang sama dengan respons `400` dari `POST /v3/events/`; `event_id` yang digunakan kembali dengan konten berbeda dilaporkan sebagai string di bawah `errors.event_id`."
                          },
                          "event_uuid": {
                            "type": "string",
                            "format": "uuid",
                            "description": "Hanya item yang diterima dan diputar ulang."
                          },
                          "status": {
                            "type": "string",
                            "enum": [
                              "ACCEPTED",
                              "APPROVED",
                              "IN_REVIEW",
                              "DECLINED"
                            ],
                            "description": "Hanya item yang diterima dan diputar ulang."
                          },
                          "score": {
                            "type": "integer",
                            "description": "Hanya item yang diterima dan diputar ulang."
                          },
                          "rules_evaluated_count": {
                            "type": "integer",
                            "description": "Hanya item yang diterima dan diputar ulang."
                          },
                          "rules_matched_count": {
                            "type": "integer",
                            "description": "Hanya item yang diterima dan diputar ulang."
                          },
                          "correlation_pending": {
                            "type": "boolean",
                            "description": "Hanya item yang diterima dan diputar ulang."
                          },
                          "retention_class": {
                            "type": "string",
                            "enum": [
                              "low_value",
                              "standard",
                              "risk_relevant",
                              "monetary_or_compliance"
                            ],
                            "description": "Hanya item yang diterima dan diputar ulang."
                          },
                          "expires_at": {
                            "type": "string",
                            "format": "date-time",
                            "nullable": true,
                            "description": "Hanya item yang diterima dan diputar ulang."
                          },
                          "idempotent_replay": {
                            "type": "boolean",
                            "description": "Hanya item yang diterima dan diputar ulang."
                          },
                          "rule_matches": {
                            "type": "array",
                            "description": "Hanya item yang diterima dan diputar ulang.",
                            "items": {
                              "type": "object",
                              "required": [
                                "rule_id",
                                "library_key",
                                "mode",
                                "is_async"
                              ],
                              "properties": {
                                "rule_id": {
                                  "type": "string",
                                  "format": "uuid",
                                  "description": "UUID aturan."
                                },
                                "library_key": {
                                  "type": "string",
                                  "nullable": true,
                                  "description": "Kunci pustaka saat aturan dipasang dari pustaka aturan, jika tidak maka null."
                                },
                                "mode": {
                                  "type": "string",
                                  "enum": [
                                    "ACTIVE",
                                    "TEST"
                                  ],
                                  "description": "Aturan `TEST` mencatat kecocokan tetapi tidak menerapkan tindakan apa pun."
                                },
                                "is_async": {
                                  "type": "boolean",
                                  "description": "`true` saat kecocokan berasal dari proses asinkron."
                                }
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "All landed": {
                    "value": {
                      "accepted_count": 1,
                      "replayed_count": 1,
                      "rejected_count": 0,
                      "results": [
                        {
                          "index": 0,
                          "outcome": "accepted",
                          "event_uuid": "33333333-4444-5555-6666-777777777777",
                          "event_id": "login-2026-10-17-000001",
                          "status": "ACCEPTED",
                          "score": 0,
                          "rules_evaluated_count": 6,
                          "rules_matched_count": 0,
                          "correlation_pending": false,
                          "retention_class": "standard",
                          "expires_at": "2026-11-16T09:15:02.481000Z",
                          "idempotent_replay": false,
                          "rule_matches": []
                        },
                        {
                          "index": 1,
                          "outcome": "replayed",
                          "event_uuid": "11111111-2222-3333-4444-555555555555",
                          "event_id": "deposit-2026-10-17-000002",
                          "status": "ACCEPTED",
                          "score": 0,
                          "rules_evaluated_count": 6,
                          "rules_matched_count": 0,
                          "correlation_pending": false,
                          "retention_class": "monetary_or_compliance",
                          "expires_at": null,
                          "idempotent_replay": true,
                          "rule_matches": []
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "207": {
            "description": "Setidaknya satu item ditolak. Item lainnya disimpan; perbaiki dan kirim ulang hanya item yang ditolak (mengirim ulang item yang diterima aman dilakukan, statusnya kembali sebagai `replayed`).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "accepted_count",
                    "replayed_count",
                    "rejected_count",
                    "results"
                  ],
                  "properties": {
                    "accepted_count": {
                      "type": "integer",
                      "minimum": 0,
                      "description": "Item disimpan dan dievaluasi."
                    },
                    "replayed_count": {
                      "type": "integer",
                      "minimum": 0,
                      "description": "Item yang sudah tersimpan dengan konten yang sama."
                    },
                    "rejected_count": {
                      "type": "integer",
                      "minimum": 0,
                      "description": "Item tidak disimpan."
                    },
                    "results": {
                      "type": "array",
                      "description": "Satu entri per item, sesuai urutan permintaan.",
                      "items": {
                        "type": "object",
                        "description": "Hasil dari satu item. Item yang diterima dan diputar ulang juga memuat setiap kolom dari `MonitoringEventIngestResult`; item yang ditolak justru memuat `event_id` dan `errors`.",
                        "required": [
                          "index",
                          "outcome"
                        ],
                        "properties": {
                          "index": {
                            "type": "integer",
                            "minimum": 0,
                            "description": "Posisi item dalam array `events` Anda."
                          },
                          "outcome": {
                            "type": "string",
                            "enum": [
                              "accepted",
                              "replayed",
                              "rejected"
                            ],
                            "description": "`accepted`: disimpan dan dievaluasi. `replayed`: sudah disimpan dengan konten yang sama. `rejected`: tidak disimpan; lihat `errors`."
                          },
                          "event_id": {
                            "type": "string",
                            "nullable": true,
                            "description": "`event_id` Anda. Pada item yang ditolak oleh validasi, nilai ini dibaca dari kunci snake_case `event_id` milik item tersebut, sehingga bernilai null ketika item tersebut menghilangkannya atau mengirimkan alias `eventId`."
                          },
                          "errors": {
                            "type": "object",
                            "additionalProperties": true,
                            "description": "Hanya item yang ditolak. Kesalahan validasi dikelompokkan berdasarkan kolom, dalam format yang sama dengan respons `400` dari `POST /v3/events/`; `event_id` yang digunakan kembali dengan konten berbeda dilaporkan sebagai string di bawah `errors.event_id`."
                          },
                          "event_uuid": {
                            "type": "string",
                            "format": "uuid",
                            "description": "Hanya item yang diterima dan diputar ulang."
                          },
                          "status": {
                            "type": "string",
                            "enum": [
                              "ACCEPTED",
                              "APPROVED",
                              "IN_REVIEW",
                              "DECLINED"
                            ],
                            "description": "Hanya item yang diterima dan diputar ulang."
                          },
                          "score": {
                            "type": "integer",
                            "description": "Hanya item yang diterima dan diputar ulang."
                          },
                          "rules_evaluated_count": {
                            "type": "integer",
                            "description": "Hanya item yang diterima dan diputar ulang."
                          },
                          "rules_matched_count": {
                            "type": "integer",
                            "description": "Hanya item yang diterima dan diputar ulang."
                          },
                          "correlation_pending": {
                            "type": "boolean",
                            "description": "Hanya item yang diterima dan diputar ulang."
                          },
                          "retention_class": {
                            "type": "string",
                            "enum": [
                              "low_value",
                              "standard",
                              "risk_relevant",
                              "monetary_or_compliance"
                            ],
                            "description": "Hanya item yang diterima dan diputar ulang."
                          },
                          "expires_at": {
                            "type": "string",
                            "format": "date-time",
                            "nullable": true,
                            "description": "Hanya item yang diterima dan diputar ulang."
                          },
                          "idempotent_replay": {
                            "type": "boolean",
                            "description": "Hanya item yang diterima dan diputar ulang."
                          },
                          "rule_matches": {
                            "type": "array",
                            "description": "Hanya item yang diterima dan diputar ulang.",
                            "items": {
                              "type": "object",
                              "required": [
                                "rule_id",
                                "library_key",
                                "mode",
                                "is_async"
                              ],
                              "properties": {
                                "rule_id": {
                                  "type": "string",
                                  "format": "uuid",
                                  "description": "UUID aturan."
                                },
                                "library_key": {
                                  "type": "string",
                                  "nullable": true,
                                  "description": "Kunci pustaka saat aturan dipasang dari pustaka aturan, jika tidak maka null."
                                },
                                "mode": {
                                  "type": "string",
                                  "enum": [
                                    "ACTIVE",
                                    "TEST"
                                  ],
                                  "description": "Aturan `TEST` mencatat kecocokan tetapi tidak menerapkan tindakan apa pun."
                                },
                                "is_async": {
                                  "type": "boolean",
                                  "description": "`true` saat kecocokan berasal dari proses asinkron."
                                }
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "Partial success": {
                    "value": {
                      "accepted_count": 1,
                      "replayed_count": 0,
                      "rejected_count": 2,
                      "results": [
                        {
                          "index": 0,
                          "outcome": "accepted",
                          "event_uuid": "33333333-4444-5555-6666-777777777777",
                          "event_id": "login-2026-10-17-000001",
                          "status": "ACCEPTED",
                          "score": 0,
                          "rules_evaluated_count": 6,
                          "rules_matched_count": 0,
                          "correlation_pending": false,
                          "retention_class": "standard",
                          "expires_at": "2026-11-16T09:15:02.481000Z",
                          "idempotent_replay": false,
                          "rule_matches": []
                        },
                        {
                          "index": 1,
                          "event_id": "deposit-2026-10-17-000002",
                          "outcome": "rejected",
                          "errors": {
                            "payload": [
                              "payment.deposit_completed requires: payment_method, status."
                            ]
                          }
                        },
                        {
                          "index": 2,
                          "event_id": "login-2026-10-16-000777",
                          "outcome": "rejected",
                          "errors": {
                            "event_id": "event_id 'login-2026-10-16-000777' already exists with a different payload."
                          }
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Batch itu sendiri tidak valid: `events` tidak ada atau bukan array, kosong, atau memiliki lebih dari 500 item. Tidak ada yang disimpan; bagi batch yang besar.",
            "content": {
              "application/json": {
                "examples": {
                  "Not a list": {
                    "value": {
                      "events": "Expected a list of events."
                    }
                  },
                  "Empty": {
                    "value": {
                      "events": "At least one event is required."
                    }
                  },
                  "Too many": {
                    "value": {
                      "events": "A batch accepts at most 500 events; received 612."
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Kunci API dengan cakupan terbatas telah kedaluwarsa. Hanya kunci yang kedaluwarsa yang menerima `401`; kunci yang hilang atau tidak valid menerima `403`.",
            "content": {
              "application/json": {
                "examples": {
                  "Expired key": {
                    "value": {
                      "detail": "This API key has expired."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "`x-api-key` tidak ada (kunci yang salah, dicabut, atau kedaluwarsa menghasilkan `401`), kunci dengan pembatasan cakupan tanpa `transactions: write`, kunci yang dibatasi pada alur kerja tertentu atau pada sesi yang disetujui (kunci semacam itu tidak pernah mengakses data pemantauan transaksi), atau permintaan dari luar allowlist IP milik kunci tersebut. Juga dikembalikan dengan `code: event_monitoring_disabled` saat penyerapan event dinonaktifkan untuk aplikasi; tidak ada yang disimpan dalam kasus tersebut, dan pemeriksaan berjalan sebelum body divalidasi.",
            "content": {
              "application/json": {
                "examples": {
                  "Event monitoring disabled": {
                    "value": {
                      "detail": "Event monitoring is not enabled for this application. Turn on event ingestion in the transaction monitoring settings before submitting events.",
                      "code": "event_monitoring_disabled"
                    }
                  },
                  "Missing or invalid API key": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Scoped key without access": {
                    "value": {
                      "detail": "This API key has no write access to transactions."
                    }
                  },
                  "Key limited to workflows or approved sessions": {
                    "value": {
                      "detail": "This API key only reaches sessions inside its workflow or status limits, so it can't use this endpoint."
                    }
                  },
                  "IP not allowed": {
                    "value": {
                      "detail": "This API key can't be used from this IP address."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Batas laju terlampaui: pembuatan transaksi dan penyerapan event (`POST /v3/transactions/`, `POST /v3/events/`, `POST /v3/events/batch/`) berbagi anggaran sebanyak 600 permintaan per menit per kunci API, terpisah dari anggaran 300 permintaan yang digunakan bersama oleh semua permintaan tulis lainnya. Tunggu `Retry-After` detik, lalu coba lagi.",
            "headers": {
              "Retry-After": {
                "description": "Detik yang harus ditunggu sebelum mencoba lagi, dibulatkan ke atas agar percobaan berikutnya berada di jendela berikutnya.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "example": 30
                }
              }
            },
            "content": {
              "application/json": {
                "examples": {
                  "Throttled": {
                    "value": {
                      "detail": "Ingestion rate limit exceeded. You can make up to 600 requests per minute."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/events/sdk-token/": {
      "post": {
        "summary": "Buat token SDK pemantauan",
        "description": "Buat kredensial perangkat berumur pendek yang terikat pada satu subjek, sehingga aplikasi web atau seluler Anda dapat mengirim event pengguna tersebut langsung ke Didit tanpa kunci API. Aplikasi mengirimkan `monitoring_token` yang dikembalikan dalam header `X-Monitoring-Token` ke jalur perangkat (`POST /v1/events/` dan `POST /v1/events/batch/`), di mana subjek selalu ditimpa dengan `vendor_data` ini, event di luar `allowed_event_categories` ditolak, setiap event yang dikirimkan menghabiskan satu penggunaan, dan permintaan yang `Origin`-nya tidak sama dengan `bind_to_origin` ditolak. Panggil endpoint ini hanya dari backend Anda; pembuatan hanya membuat kredensial dan tidak ada yang lain (tidak ada pengguna yang dibuat). Penerimaan event harus diaktifkan untuk aplikasi, jika tidak, endpoint ini mengembalikan `403` dengan `code: event_monitoring_disabled` daripada membuat kredensial yang tidak akan pernah bisa menulis. Kunci API dengan pembatasan cakupan memerlukan `transactions: write`. Lihat [Pengiriman event SDK](https://docs.didit.me/id/transaction-monitoring/sdk-event-submission).",
        "operationId": "create_monitoring_event_sdk_token",
        "x-didit-sdk": {
          "resource": "monitoring_events",
          "method": "create_sdk_token",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Monitoring Events"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "description": "alias camelCase diterima: `vendorData`, `entityType`, `allowedEventCategories`, `ttlSeconds`, `maxUses`, `bindToOrigin`.",
                "required": [
                  "vendor_data"
                ],
                "properties": {
                  "vendor_data": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 255,
                    "description": "ID Anda untuk subjek yang memiliki setiap event yang dikirimkan dengan kredensial ini."
                  },
                  "entity_type": {
                    "type": "string",
                    "maxLength": 32,
                    "default": "individual",
                    "description": "`company` mengikat subjek perusahaan; nilai lainnya (default `individual`) mengikat perorangan."
                  },
                  "allowed_event_categories": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "enum": [
                        "auth",
                        "session",
                        "gameplay",
                        "bonus",
                        "affiliate",
                        "payment",
                        "dispute",
                        "security",
                        "responsible_gambling",
                        "custom"
                      ]
                    },
                    "description": "Kategori yang dapat dikirimkan oleh kredensial. Hilangkan atau kirim `[]` untuk mengizinkan setiap kategori."
                  },
                  "ttl_seconds": {
                    "type": "integer",
                    "minimum": 60,
                    "maximum": 86400,
                    "default": 900,
                    "description": "Masa berlaku kredensial dalam detik."
                  },
                  "max_uses": {
                    "type": "integer",
                    "minimum": 1,
                    "nullable": true,
                    "default": 1000,
                    "description": "Jumlah event yang dapat dikirimkan oleh kredensial (satu batch menggunakan satu penggunaan untuk setiap event). Kirim `null` untuk tanpa batas dalam masa berlaku."
                  },
                  "bind_to_origin": {
                    "type": "string",
                    "maxLength": 255,
                    "nullable": true,
                    "description": "Jika diatur, header `Origin` browser dari setiap permintaan perangkat harus sama persis dengan nilai ini; permintaan tanpa `Origin` akan ditolak."
                  }
                }
              },
              "example": {
                "vendor_data": "user-42",
                "allowed_event_categories": [
                  "auth",
                  "session",
                  "gameplay"
                ],
                "ttl_seconds": 900,
                "max_uses": 1000,
                "bind_to_origin": "https://app.example.com"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://verification.didit.me/v3/events/sdk-token/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"vendor_data\": \"user-42\",\n    \"allowed_event_categories\": [\"auth\", \"session\", \"gameplay\"],\n    \"ttl_seconds\": 900,\n    \"max_uses\": 1000,\n    \"bind_to_origin\": \"https://app.example.com\"\n  }'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.monitoring_events.create_sdk_token(\n    vendor_data=\"user-42\",\n    allowed_event_categories=[\"auth\", \"session\", \"gameplay\"],\n    ttl_seconds=900,\n    max_uses=1000,\n    bind_to_origin=\"https://app.example.com\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.monitoringEvents.createSdkToken({\n  vendor_data: \"user-42\",\n  allowed_event_categories: [\"auth\", \"session\", \"gameplay\"],\n  ttl_seconds: 900,\n  max_uses: 1000,\n  bind_to_origin: \"https://app.example.com\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.MonitoringEvents.CreateSDKToken(ctx, didit.MonitoringEventsCreateSDKTokenParams{\n\tVendorData:             \"user-42\",\n\tAllowedEventCategories: didit.Some([]didit.MonitoringEventsCreateSDKTokenParamsAllowedEventCategories{\"auth\", \"session\", \"gameplay\"}),\n\tTTLSeconds:             didit.Int(900),\n\tMaxUses:                didit.Int(1000),\n\tBindToOrigin:           didit.String(\"https://app.example.com\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.List;\nimport me.didit.Didit;\nimport me.didit.types.MonitoringEventsCreateSdkTokenParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.monitoringEvents().createSdkToken(MonitoringEventsCreateSdkTokenParams.builder()\n        .vendorData(\"user-42\")\n        .allowedEventCategories(List.of(MonitoringEventsCreateSdkTokenParams.AllowedEventCategories.of(\"auth\"), MonitoringEventsCreateSdkTokenParams.AllowedEventCategories.of(\"session\"), MonitoringEventsCreateSdkTokenParams.AllowedEventCategories.of(\"gameplay\")))\n        .ttlSeconds(900L)\n        .maxUses(1000L)\n        .bindToOrigin(\"https://app.example.com\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->monitoringEvents->createSdkToken([\n    'vendor_data' => 'user-42',\n    'allowed_event_categories' => ['auth', 'session', 'gameplay'],\n    'ttl_seconds' => 900,\n    'max_uses' => 1000,\n    'bind_to_origin' => 'https://app.example.com',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.monitoring_events.create_sdk_token(\n  vendor_data: \"user-42\",\n  allowed_event_categories: [\"auth\", \"session\", \"gameplay\"],\n  ttl_seconds: 900,\n  max_uses: 1000,\n  bind_to_origin: \"https://app.example.com\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.MonitoringEvents.CreateSdkTokenAsync(new MonitoringEventsCreateSdkTokenParams\n{\n    VendorData = \"user-42\",\n    AllowedEventCategories = new MonitoringEventsCreateSdkTokenParamsAllowedEventCategories[] { \"auth\", \"session\", \"gameplay\" },\n    TtlSeconds = 900,\n    MaxUses = 1000,\n    BindToOrigin = \"https://app.example.com\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "201": {
            "description": "Kredensial telah diterbitkan. Berikan `monitoring_token` ke aplikasi dan perlakukan sebagai rahasia hingga `expires_at`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "monitoring_token",
                    "expires_at",
                    "allowed_event_categories",
                    "max_uses",
                    "bind_to_origin"
                  ],
                  "properties": {
                    "monitoring_token": {
                      "type": "string",
                      "description": "Kredensial perangkat (token URL-safe 43 karakter). Kirim kredensial ini di header `X-Monitoring-Token`."
                    },
                    "expires_at": {
                      "type": "string",
                      "format": "date-time",
                      "description": "Waktu ketika kredensial tidak lagi diterima."
                    },
                    "allowed_event_categories": {
                      "type": "array",
                      "items": {
                        "type": "string",
                        "enum": [
                          "auth",
                          "session",
                          "gameplay",
                          "bonus",
                          "affiliate",
                          "payment",
                          "dispute",
                          "security",
                          "responsible_gambling",
                          "custom"
                        ]
                      },
                      "description": "Kategori yang dapat dikirimkan oleh kredensial; `[]` berarti setiap kategori."
                    },
                    "max_uses": {
                      "type": "integer",
                      "nullable": true,
                      "description": "Anggaran peristiwa kredensial; null berarti tidak ada batas."
                    },
                    "bind_to_origin": {
                      "type": "string",
                      "nullable": true,
                      "description": "Asal tempat kredensial terikat, atau null."
                    }
                  }
                },
                "example": {
                  "monitoring_token": "q7ZtR2xKp9VbN4mWc8LdH1sYfJ3gT6uEaQ0oPiXzBkC",
                  "expires_at": "2026-10-17T09:30:02.481000Z",
                  "allowed_event_categories": [
                    "auth",
                    "session",
                    "gameplay"
                  ],
                  "max_uses": 1000,
                  "bind_to_origin": "https://app.example.com"
                }
              }
            }
          },
          "400": {
            "description": "Validasi gagal: `vendor_data` tidak ada, `ttl_seconds` di luar 60 hingga 86400, `max_uses` di bawah 1, atau kategori tidak dikenal (diindeks berdasarkan posisinya dalam array).",
            "content": {
              "application/json": {
                "examples": {
                  "Missing vendor_data": {
                    "value": {
                      "vendor_data": [
                        "This field is required."
                      ]
                    }
                  },
                  "ttl_seconds too short": {
                    "value": {
                      "ttl_seconds": [
                        "Ensure this value is greater than or equal to 60."
                      ]
                    }
                  },
                  "Unknown category": {
                    "value": {
                      "allowed_event_categories": {
                        "1": [
                          "\"login\" is not a valid choice."
                        ]
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Kunci API dengan cakupan terbatas telah kedaluwarsa. Hanya kunci yang kedaluwarsa yang menerima `401`; kunci yang hilang atau tidak valid menerima `403`.",
            "content": {
              "application/json": {
                "examples": {
                  "Expired key": {
                    "value": {
                      "detail": "This API key has expired."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "`x-api-key` tidak ada (kunci yang salah, dicabut, atau kedaluwarsa menghasilkan `401`), kunci dengan pembatasan cakupan tanpa `transactions: write`, kunci yang dibatasi pada alur kerja tertentu atau pada sesi yang disetujui (kunci semacam itu tidak pernah mengakses data pemantauan transaksi), atau permintaan dari luar allowlist IP milik kunci tersebut. Juga dikembalikan dengan `code: event_monitoring_disabled` saat penyerapan event dinonaktifkan untuk aplikasi; tidak ada yang disimpan dalam kasus tersebut, dan pemeriksaan berjalan sebelum body divalidasi.",
            "content": {
              "application/json": {
                "examples": {
                  "Event monitoring disabled": {
                    "value": {
                      "detail": "Event monitoring is not enabled for this application. Turn on event ingestion in the transaction monitoring settings before submitting events.",
                      "code": "event_monitoring_disabled"
                    }
                  },
                  "Missing or invalid API key": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Scoped key without access": {
                    "value": {
                      "detail": "This API key has no write access to transactions."
                    }
                  },
                  "Key limited to workflows or approved sessions": {
                    "value": {
                      "detail": "This API key only reaches sessions inside its workflow or status limits, so it can't use this endpoint."
                    }
                  },
                  "IP not allowed": {
                    "value": {
                      "detail": "This API key can't be used from this IP address."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Batas laju terlampaui: permintaan tulis (`POST`, `PATCH`, `DELETE`) berbagi anggaran sebanyak 300 permintaan per menit per kunci API. Tunggu `Retry-After` detik, lalu coba lagi.",
            "headers": {
              "Retry-After": {
                "description": "Detik untuk menunggu sebelum mencoba lagi.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "example": 30
                }
              }
            },
            "content": {
              "application/json": {
                "examples": {
                  "Throttled": {
                    "value": {
                      "detail": "Write request rate limit exceeded. You can make up to 300 requests per minute."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/events/{event_uuid}/": {
      "get": {
        "summary": "Dapatkan event pemantauan",
        "description": "Ambil satu event pemantauan beserta semua data yang dikembalikan daftar ditambah payload, nilai kustom, konteks perangkat, asal-usul kolom (`field_sources`), kolom domain yang dipromosikan, `expires_at`, setiap eksekusi aturan yang cocok beserta buktinya, pengayaan IP, dan tag yang dilampirkan aturan. Selama `correlation_pending` bernilai `true`, aturan asinkron masih harus dijalankan; baca kembali event tersebut beberapa menit kemudian untuk mendapatkan `status`, `score`, dan `rule_runs` akhir. Operasi baca berfungsi baik penyerapan event diaktifkan maupun tidak. Kunci API dengan pembatasan cakupan memerlukan `transactions: read`. Lihat [Bukti](https://docs.didit.me/id/transaction-monitoring/event-rules#bukti) dan [Pengayaan IP](https://docs.didit.me/id/transaction-monitoring/ip-enrichment).",
        "operationId": "get_monitoring_event",
        "x-didit-sdk": {
          "resource": "monitoring_events",
          "method": "retrieve",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Monitoring Events"
        ],
        "parameters": [
          {
            "name": "event_uuid",
            "in": "path",
            "required": true,
            "description": "Pengidentifikasi Didit untuk event tersebut (`event_uuid` dari respons pembuatan, batch, daftar, atau linimasa), bukan `event_id` Anda sendiri.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "11111111-2222-3333-4444-555555555555"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/events/11111111-2222-3333-4444-555555555555/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.monitoring_events.retrieve(\n    \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.monitoringEvents.retrieve(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.MonitoringEvents.Retrieve(ctx, \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.monitoringEvents().retrieve(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->monitoringEvents->retrieve('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.monitoring_events.retrieve(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.MonitoringEvents.RetrieveAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "Event beserta buktinya.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MonitoringEventDetail"
                },
                "examples": {
                  "Login from a VPN, in review": {
                    "value": {
                      "event_uuid": "33333333-4444-5555-6666-777777777777",
                      "event_id": "login-2026-10-17-000001",
                      "event_category": "auth",
                      "action_type": "login",
                      "occurred_at": "2026-10-17T09:15:02.481000Z",
                      "received_at": "2026-10-17T09:15:02.903114Z",
                      "status": "IN_REVIEW",
                      "score": 40,
                      "subject_vendor_data": "user-42",
                      "subject_entity_type": "individual",
                      "subject_uuid": "66666666-7777-8888-9999-000000000000",
                      "counterparty_vendor_data": null,
                      "session_id": "web-session-abc",
                      "device_fingerprint": "fp-a8c1",
                      "ip_address": "203.0.113.42",
                      "ip_country": "ES",
                      "amount": null,
                      "currency": null,
                      "game_id": null,
                      "round_id": null,
                      "bonus_id": null,
                      "affiliate_code": null,
                      "payment_reference_id": null,
                      "retention_class": "risk_relevant",
                      "rules_matched_count": 1,
                      "correlation_pending": false,
                      "is_droppable": true,
                      "payload": {
                        "method": "password"
                      },
                      "custom_values": {
                        "vip_tier": "gold",
                        "vpn_or_proxy_detected": true
                      },
                      "device_context": {
                        "fingerprint": "fp-a8c1",
                        "network_context": {
                          "ip_address": "203.0.113.42",
                          "ip_country": "Spain",
                          "ip_country_code": "ES",
                          "ip_city": "Madrid",
                          "asn_number": 64500,
                          "asn_organization": "Example Networks",
                          "is_vpn_or_tor": true,
                          "is_data_center": false
                        }
                      },
                      "field_sources": {
                        "subject.vendor_data": "customer",
                        "event_category": "customer",
                        "action_type": "customer",
                        "occurred_at": "customer",
                        "received_at": "server",
                        "payload.method": "customer",
                        "session.session_id": "customer",
                        "session.sequence": "customer",
                        "device_context.fingerprint": "customer",
                        "device_context.network_context.ip_address": "customer",
                        "device_context.network_context.ip_country": "server",
                        "device_context.network_context.ip_country_code": "server",
                        "device_context.network_context.ip_city": "server",
                        "device_context.network_context.asn_number": "server",
                        "device_context.network_context.asn_organization": "server",
                        "device_context.network_context.is_vpn_or_tor": "server",
                        "device_context.network_context.is_data_center": "server"
                      },
                      "session_sequence": 142,
                      "table_id": null,
                      "hand_id": null,
                      "match_id": null,
                      "market_id": null,
                      "side": null,
                      "role": null,
                      "net_result_amount": null,
                      "payment_fingerprint": null,
                      "instrument_reference_hash": null,
                      "withdrawal_address_hash": null,
                      "dispute_id": null,
                      "chargeback_id": null,
                      "changed_field": null,
                      "identity_match_ref": null,
                      "schema_version": 1,
                      "expires_at": "2027-01-15T09:15:02.481000Z",
                      "rules_evaluated_count": 6,
                      "rule_runs": [
                        {
                          "rule_uuid": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee",
                          "rule_title": "Login from VPN or Tor",
                          "library_key": null,
                          "matched": true,
                          "mode": "ACTIVE",
                          "is_async": false,
                          "severity": "MEDIUM",
                          "score_delta": 40,
                          "action_summary": "score +40; add_tag:VPN_LOGIN",
                          "matched_payload": [
                            {
                              "field": "event.ip.is_vpn_or_tor",
                              "operator": "eq",
                              "expected_value": true,
                              "current_value": true,
                              "matched": true,
                              "group_index": null,
                              "group_logic": "AND",
                              "field_source": "server"
                            }
                          ],
                          "created_at": "2026-10-17T09:15:02.951207Z"
                        }
                      ],
                      "ip_enrichment": {
                        "ip_country_code": "ES",
                        "ip_city": "Madrid",
                        "asn_number": 64500,
                        "asn_organization": "Example Networks",
                        "is_vpn_or_tor": true,
                        "is_data_center": false,
                        "proxy_type": null,
                        "last_enriched_at": "2026-10-17T09:15:02.910442Z"
                      },
                      "subject_profile": null,
                      "tags": [
                        "VPN_LOGIN"
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Kunci API dengan cakupan terbatas telah kedaluwarsa. Hanya kunci yang kedaluwarsa yang menerima `401`; kunci yang hilang atau tidak valid menerima `403`.",
            "content": {
              "application/json": {
                "examples": {
                  "Expired key": {
                    "value": {
                      "detail": "This API key has expired."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "`x-api-key` tidak ada (kunci yang salah, dicabut, atau kedaluwarsa menghasilkan `401`), kunci dengan pembatasan cakupan tanpa `transactions: read`, kunci yang dibatasi pada alur kerja tertentu atau pada sesi yang disetujui (kunci semacam itu tidak pernah mengakses data pemantauan transaksi), atau permintaan dari luar allowlist IP milik kunci tersebut.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing or invalid API key": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Scoped key without access": {
                    "value": {
                      "detail": "This API key has no read access to transactions."
                    }
                  },
                  "Key limited to workflows or approved sessions": {
                    "value": {
                      "detail": "This API key only reaches sessions inside its workflow or status limits, so it can't use this endpoint."
                    }
                  },
                  "IP not allowed": {
                    "value": {
                      "detail": "This API key can't be used from this IP address."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Tidak ada event dengan `event_uuid` ini di dalam aplikasi: event tidak pernah disimpan, telah dihapus, atau milik aplikasi lain. Segmen jalur yang bukan berupa UUID tidak cocok dengan rute dan juga mengembalikan `404`.",
            "content": {
              "application/json": {
                "examples": {
                  "Not found": {
                    "value": {
                      "detail": "No MonitoringEvent matches the given query."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Batas laju terlampaui: permintaan `GET` berbagi anggaran sebanyak 600 permintaan per menit per kunci API. Tunggu `Retry-After` detik, lalu coba lagi.",
            "headers": {
              "Retry-After": {
                "description": "Detik untuk menunggu sebelum mencoba lagi.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "example": 30
                }
              }
            },
            "content": {
              "application/json": {
                "examples": {
                  "Throttled": {
                    "value": {
                      "detail": "GET request rate limit exceeded. You can make up to 600 requests per minute."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/events/subjects/{vendor_data}/": {
      "get": {
        "summary": "Dapatkan lini masa peristiwa subjek",
        "description": "Daftar setiap event pemantauan dari satu subjek, terbaru berdasarkan `occurred_at` lebih dahulu. `vendor_data` bersifat unik hanya dalam satu jenis entitas, sehingga ID yang sama dapat merujuk ke individu dan perusahaan: `entity_type` memilih linimasa mana yang Anda dapatkan, dan secara default bernilai `individual`, sehingga event perusahaan memerlukan `entity_type=company`. Filter dari `GET /v3/events/` juga berlaku, dan `vendor_data` tanpa event mengembalikan halaman kosong alih-alih `404`. Kunci API dengan cakupan khusus memerlukan `transactions: read`. Lihat [Membaca kembali event](https://docs.didit.me/id/transaction-monitoring/events#membaca-kembali-event).",
        "operationId": "get_monitoring_event_subject_timeline",
        "x-didit-sdk": {
          "resource": "monitoring_events",
          "method": "retrieve_subject_timeline",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Monitoring Events"
        ],
        "parameters": [
          {
            "name": "vendor_data",
            "in": "path",
            "required": true,
            "description": "ID Anda untuk subjek (`subject.vendor_data` dari event-nya). Lakukan URL-encode; nilai yang mengandung `/` tidak dapat ditangani oleh endpoint ini.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255
            },
            "example": "user-42"
          },
          {
            "name": "entity_type",
            "in": "query",
            "required": false,
            "description": "`company` mengembalikan perusahaan dengan `vendor_data` ini; nilai lain apa pun, atau tanpa nilai, mengembalikan individu. `subject_entity_type` diterima sebagai alias jika `entity_type` tidak ada.",
            "schema": {
              "type": "string",
              "enum": [
                "individual",
                "company"
              ],
              "default": "individual"
            },
            "example": "individual"
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Jumlah event maksimum per halaman. Defaultnya 50. Nilai di atas 1000000 mengembalikan `400`; nilai non-numerik, nol, atau negatif akan dialihkan ke 50.",
            "schema": {
              "type": "integer",
              "default": 50,
              "minimum": 1,
              "maximum": 1000000
            },
            "example": 50
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "description": "Jumlah event yang dilewati. Default-nya 0. Lebih disarankan mengikuti URL `next` dari respons.",
            "schema": {
              "type": "integer",
              "default": 0,
              "minimum": 0,
              "maximum": 1000000
            },
            "example": 0
          },
          {
            "name": "event_category",
            "in": "query",
            "required": false,
            "description": "Hanya event dalam kategori ini. Ulangi parameter untuk beberapa nilai (`?event_category=payment&event_category=dispute`); event yang cocok dengan salah satunya akan dikembalikan.",
            "style": "form",
            "explode": true,
            "schema": {
              "type": "array",
              "items": {
                "type": "string",
                "enum": [
                  "auth",
                  "session",
                  "gameplay",
                  "bonus",
                  "affiliate",
                  "payment",
                  "dispute",
                  "security",
                  "responsible_gambling",
                  "custom"
                ]
              }
            },
            "example": [
              "payment",
              "dispute"
            ]
          },
          {
            "name": "action_type",
            "in": "query",
            "required": false,
            "description": "Hanya event dengan jenis tindakan ini (persis, peka huruf besar-kecil). Ulangi untuk beberapa nilai.",
            "style": "form",
            "explode": true,
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "example": [
              "deposit_completed",
              "chargeback_opened"
            ]
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "description": "Hanya event dengan status ini. Ulangi untuk beberapa nilai.",
            "style": "form",
            "explode": true,
            "schema": {
              "type": "array",
              "items": {
                "type": "string",
                "enum": [
                  "ACCEPTED",
                  "APPROVED",
                  "IN_REVIEW",
                  "DECLINED"
                ]
              }
            },
            "example": [
              "IN_REVIEW",
              "DECLINED"
            ]
          },
          {
            "name": "retention_class",
            "in": "query",
            "required": false,
            "description": "Hanya event dalam kelas retensi ini. Ulangi untuk beberapa nilai.",
            "style": "form",
            "explode": true,
            "schema": {
              "type": "array",
              "items": {
                "type": "string",
                "enum": [
                  "low_value",
                  "standard",
                  "risk_relevant",
                  "monetary_or_compliance"
                ]
              }
            },
            "example": [
              "risk_relevant"
            ]
          },
          {
            "name": "business_vendor_data",
            "in": "query",
            "required": false,
            "description": "Kecocokan persis pada `business.vendor_data` yang dikirim bersama event.",
            "schema": {
              "type": "string"
            },
            "example": "merchant-7"
          },
          {
            "name": "session_id",
            "in": "query",
            "required": false,
            "description": "Kecocokan persis pada `session.session_id`.",
            "schema": {
              "type": "string"
            },
            "example": "web-session-abc"
          },
          {
            "name": "device_fingerprint",
            "in": "query",
            "required": false,
            "description": "Kecocokan persis pada `device_context.fingerprint`.",
            "schema": {
              "type": "string"
            },
            "example": "fp-a8c1"
          },
          {
            "name": "ip_address",
            "in": "query",
            "required": false,
            "description": "Kecocokan persis pada alamat IP peristiwa.",
            "schema": {
              "type": "string"
            },
            "example": "203.0.113.42"
          },
          {
            "name": "game_id",
            "in": "query",
            "required": false,
            "description": "Kecocokan persis pada `game_id` yang dipromosikan.",
            "schema": {
              "type": "string"
            },
            "example": "poker-holdem-01"
          },
          {
            "name": "round_id",
            "in": "query",
            "required": false,
            "description": "Kecocokan persis pada `round_id` yang dipromosikan.",
            "schema": {
              "type": "string"
            },
            "example": "round-88231"
          },
          {
            "name": "affiliate_code",
            "in": "query",
            "required": false,
            "description": "Kecocokan persis pada `affiliate_code` yang dipromosikan.",
            "schema": {
              "type": "string"
            },
            "example": "aff-summer"
          },
          {
            "name": "payment_reference_id",
            "in": "query",
            "required": false,
            "description": "Kecocokan persis pada referensi pembayaran (dari `transaction_context.payment_reference_id` atau `payload.payment_reference_id`).",
            "schema": {
              "type": "string"
            },
            "example": "dep_735"
          },
          {
            "name": "counterparty_vendor_data",
            "in": "query",
            "required": false,
            "description": "Kecocokan persis pada `counterparty_vendor_data` yang dipromosikan.",
            "schema": {
              "type": "string"
            },
            "example": "user-77"
          },
          {
            "name": "matched_only",
            "in": "query",
            "required": false,
            "description": "`true` (juga `1` atau `yes`, tidak peka huruf besar/kecil) hanya mengembalikan event yang cocok dengan setidaknya satu aturan (`rules_matched_count` di atas 0). Nilai lainnya akan diabaikan.",
            "schema": {
              "type": "boolean",
              "default": false
            },
            "example": true
          },
          {
            "name": "occurred_from",
            "in": "query",
            "required": false,
            "description": "Hanya event dengan `occurred_at` pada atau setelah waktu ini (inklusif). Kirimkan nilai ISO 8601: `2026-10-01T00:00:00Z`, offset eksplisit dengan tanda `+` yang di-percent-encode (`2026-10-01T02:00:00%2B02:00`; tanda `+` tanpa encoding akan didekodekan sebagai spasi dan nilainya tidak dapat lagi di-parse), atau tanggal saja (`2026-10-01`), yang berarti pukul 00:00:00 UTC pada hari tersebut. Nilai tanpa offset dibaca sebagai UTC. Nilai dalam format lainnya tidak diterima.",
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "example": "2026-10-01T00:00:00Z"
          },
          {
            "name": "occurred_to",
            "in": "query",
            "required": false,
            "description": "Hanya event dengan `occurred_at` pada atau sebelum waktu ini (inklusif). Tanggal saja berarti awal hari tersebut, sehingga `occurred_to=2026-10-15` tidak menyertakan sisa hari 15 Oktober; kirimkan `2026-10-15T23:59:59Z` untuk menyertakannya. Kirimkan nilai ISO 8601: `2026-10-01T00:00:00Z`, offset eksplisit dengan tanda `+` yang di-percent-encode (`2026-10-01T02:00:00%2B02:00`; tanda `+` tanpa encoding akan didekodekan sebagai spasi dan nilainya tidak dapat lagi di-parse), atau tanggal saja (`2026-10-01`), yang berarti pukul 00:00:00 UTC pada hari tersebut. Nilai tanpa offset dibaca sebagai UTC. Nilai dalam format lainnya tidak diterima.",
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "example": "2026-10-17T23:59:59Z"
          },
          {
            "name": "search",
            "in": "query",
            "required": false,
            "description": "Pencocokan substring yang tidak peka huruf besar/kecil pada `event_id`, `action_type`, `subject_vendor_data`, atau `counterparty_vendor_data`.",
            "schema": {
              "type": "string"
            },
            "example": "chargeback"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/events/subjects/user-42/?entity_type=individual&limit=50' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nfor item in client.monitoring_events.retrieve_subject_timeline(\n    \"user-42\",\n):\n    print(item)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nfor await (const item of didit.monitoringEvents.retrieveSubjectTimeline(\"user-42\")) {\n  console.log(item);\n}"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\niter := client.MonitoringEvents.RetrieveSubjectTimelineAutoPaging(ctx, \"user-42\", didit.MonitoringEventsRetrieveSubjectTimelineParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nfor (var item : client.monitoringEvents().retrieveSubjectTimeline(\"user-42\")) {\n    System.out.println(item);\n}"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\nforeach ($didit->monitoringEvents->retrieveSubjectTimeline('user-42') as $item) {\n    print_r($item->toArray());\n}"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.monitoring_events.retrieve_subject_timeline(\"user-42\").auto_paging_each do |item|\n  puts item.to_h\nend"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.MonitoringEvents.RetrieveSubjectTimelineAsync(\"user-42\"))\n{\n    Console.WriteLine(JsonSerializer.Serialize(item));\n}"
          }
        ],
        "responses": {
          "200": {
            "description": "Satu halaman event subjek.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MonitoringEventPage"
                },
                "examples": {
                  "Individual timeline": {
                    "value": {
                      "count": 2,
                      "next": null,
                      "previous": null,
                      "results": [
                        {
                          "event_uuid": "11111111-2222-3333-4444-555555555555",
                          "event_id": "chargeback-2026-10-16-000318",
                          "event_category": "dispute",
                          "action_type": "chargeback_opened",
                          "occurred_at": "2026-10-16T14:02:11Z",
                          "received_at": "2026-10-16T14:02:12.418230Z",
                          "status": "IN_REVIEW",
                          "score": 60,
                          "subject_vendor_data": "user-42",
                          "subject_entity_type": "individual",
                          "subject_uuid": "66666666-7777-8888-9999-000000000000",
                          "counterparty_vendor_data": null,
                          "session_id": null,
                          "device_fingerprint": null,
                          "ip_address": null,
                          "ip_country": null,
                          "amount": "250.000000000000000000",
                          "currency": "EUR",
                          "game_id": null,
                          "round_id": null,
                          "bonus_id": null,
                          "affiliate_code": null,
                          "payment_reference_id": "dep_735",
                          "retention_class": "monetary_or_compliance",
                          "rules_matched_count": 1,
                          "correlation_pending": false,
                          "is_droppable": false
                        },
                        {
                          "event_uuid": "22222222-3333-4444-5555-666666666666",
                          "event_id": "login-2026-10-15-000912",
                          "event_category": "auth",
                          "action_type": "login",
                          "occurred_at": "2026-10-15T08:30:00.120000Z",
                          "received_at": "2026-10-15T08:30:00.734512Z",
                          "status": "ACCEPTED",
                          "score": 0,
                          "subject_vendor_data": "user-42",
                          "subject_entity_type": "individual",
                          "subject_uuid": "66666666-7777-8888-9999-000000000000",
                          "counterparty_vendor_data": null,
                          "session_id": "web-session-abc",
                          "device_fingerprint": "fp-a8c1",
                          "ip_address": "203.0.113.42",
                          "ip_country": "ES",
                          "amount": null,
                          "currency": null,
                          "game_id": null,
                          "round_id": null,
                          "bonus_id": null,
                          "affiliate_code": null,
                          "payment_reference_id": null,
                          "retention_class": "standard",
                          "rules_matched_count": 0,
                          "correlation_pending": false,
                          "is_droppable": true
                        }
                      ]
                    }
                  },
                  "No events": {
                    "value": {
                      "count": 0,
                      "next": null,
                      "previous": null,
                      "results": []
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "`limit` atau `offset` lebih besar dari 1000000. Bagian body adalah array JSON dengan satu pesan. Nilai `limit` yang non-numerik atau non-positif dialihkan kembali ke default 50 daripada gagal.",
            "content": {
              "application/json": {
                "examples": {
                  "limit too large": {
                    "summary": "limit di atas 1000000",
                    "value": [
                      "limit must not exceed 1000000."
                    ]
                  },
                  "offset too large": {
                    "summary": "offset di atas 1000000",
                    "value": [
                      "offset must not exceed 1000000."
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Kunci API dengan cakupan terbatas telah kedaluwarsa. Hanya kunci yang kedaluwarsa yang menerima `401`; kunci yang hilang atau tidak valid menerima `403`.",
            "content": {
              "application/json": {
                "examples": {
                  "Expired key": {
                    "value": {
                      "detail": "This API key has expired."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "`x-api-key` tidak ada (kunci yang salah, dicabut, atau kedaluwarsa menghasilkan `401`), kunci dengan pembatasan cakupan tanpa `transactions: read`, kunci yang dibatasi pada alur kerja tertentu atau pada sesi yang disetujui (kunci semacam itu tidak pernah mengakses data pemantauan transaksi), atau permintaan dari luar allowlist IP milik kunci tersebut.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing or invalid API key": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Scoped key without access": {
                    "value": {
                      "detail": "This API key has no read access to transactions."
                    }
                  },
                  "Key limited to workflows or approved sessions": {
                    "value": {
                      "detail": "This API key only reaches sessions inside its workflow or status limits, so it can't use this endpoint."
                    }
                  },
                  "IP not allowed": {
                    "value": {
                      "detail": "This API key can't be used from this IP address."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Batas laju terlampaui: permintaan `GET` berbagi anggaran sebanyak 600 permintaan per menit per kunci API. Tunggu `Retry-After` detik, lalu coba lagi.",
            "headers": {
              "Retry-After": {
                "description": "Detik untuk menunggu sebelum mencoba lagi.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "example": 30
                }
              }
            },
            "content": {
              "application/json": {
                "examples": {
                  "Throttled": {
                    "value": {
                      "detail": "GET request rate limit exceeded. You can make up to 600 requests per minute."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/events/enrichment-metrics/": {
      "get": {
        "summary": "Dapatkan metrik pengayaan event",
        "description": "Mengembalikan penghitung penyerapan event dan pengayaan IP aplikasi Anda untuk suatu periode, dijumlahkan di setiap jalur (server, batch, dan perangkat), sehingga Anda dapat memantau volume event dan mengonfirmasi bahwa pengayaan diselesaikan sekali per alamat unik, bukan sekali per event. Periode ini mencakup hari ini ditambah `days` hari sebelumnya, dihitung berdasarkan tanggal kalender UTC. Ketiga rasio bernilai null jika penyebutnya nol. Kunci API dengan cakupan memerlukan `transactions: read`. Lihat [Pengayaan IP](https://docs.didit.me/id/transaction-monitoring/events#pengayaan-ip).",
        "operationId": "get_monitoring_event_enrichment_metrics",
        "x-didit-sdk": {
          "resource": "monitoring_events",
          "method": "retrieve_enrichment_metrics",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Monitoring Events"
        ],
        "parameters": [
          {
            "name": "days",
            "in": "query",
            "required": false,
            "description": "Panjang periode dalam hari. Defaultnya adalah 30; nilai dibatasi antara 1 hingga 365, dan nilai non-integer kembali ke 30. Nilai yang diterapkan dikembalikan sebagai `period_days`.",
            "schema": {
              "type": "integer",
              "default": 30,
              "minimum": 1,
              "maximum": 365
            },
            "example": 30
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/events/enrichment-metrics/?days=30' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.monitoring_events.retrieve_enrichment_metrics()\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.monitoringEvents.retrieveEnrichmentMetrics();\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.MonitoringEvents.RetrieveEnrichmentMetrics(ctx, didit.MonitoringEventsRetrieveEnrichmentMetricsParams{})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.monitoringEvents().retrieveEnrichmentMetrics();\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->monitoringEvents->retrieveEnrichmentMetrics();\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.monitoring_events.retrieve_enrichment_metrics\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.MonitoringEvents.RetrieveEnrichmentMetricsAsync();\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "Hitungan dan rasio untuk periode tersebut.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "events_ingested",
                    "events_rejected",
                    "enrichment_lookups",
                    "enrichment_cache_hits",
                    "enrichment_provider_calls",
                    "enrichment_skipped_low_value",
                    "unique_ips_seen",
                    "period_days",
                    "cache_hit_rate",
                    "unique_ip_ratio",
                    "provider_calls_per_1k_events"
                  ],
                  "properties": {
                    "events_ingested": {
                      "type": "integer",
                      "description": "Event baru disimpan. Pemutaran ulang idempoten tidak dihitung."
                    },
                    "events_rejected": {
                      "type": "integer",
                      "description": "Item yang ditolak di dalam permintaan batch (jalur server dan perangkat). Permintaan event tunggal yang ditolak tidak dihitung."
                    },
                    "enrichment_lookups": {
                      "type": "integer",
                      "description": "Event yang alamat publiknya berhasil diselesaikan, dari cache atau baru saja."
                    },
                    "enrichment_cache_hits": {
                      "type": "integer",
                      "description": "Pencarian yang dijawab dari cache."
                    },
                    "enrichment_provider_calls": {
                      "type": "integer",
                      "description": "Pencarian yang membutuhkan resolusi baru dari alamat tersebut."
                    },
                    "enrichment_skipped_low_value": {
                      "type": "integer",
                      "description": "Event telemetri bernilai rendah yang alamatnya belum diketahui. Event ini tidak pernah memicu resolusi baru sendiri."
                    },
                    "unique_ips_seen": {
                      "type": "integer",
                      "description": "Alamat yang membutuhkan resolusi baru."
                    },
                    "period_days": {
                      "type": "integer",
                      "description": "Nilai `days` yang diterapkan setelah pembatasan nilai."
                    },
                    "cache_hit_rate": {
                      "type": "number",
                      "nullable": true,
                      "description": "`enrichment_cache_hits / enrichment_lookups`, dibulatkan menjadi 4 angka desimal. Bernilai null jika tidak ada pencarian."
                    },
                    "unique_ip_ratio": {
                      "type": "number",
                      "nullable": true,
                      "description": "`unique_ips_seen / events_ingested`, dibulatkan menjadi 4 desimal. Null saat tidak ada event yang diproses."
                    },
                    "provider_calls_per_1k_events": {
                      "type": "number",
                      "nullable": true,
                      "description": "Resolusi baru per 1000 event yang diserap, dibulatkan hingga 2 desimal. Null jika tidak ada event yang diserap."
                    }
                  }
                },
                "examples": {
                  "Last 30 days": {
                    "value": {
                      "events_ingested": 128450,
                      "events_rejected": 214,
                      "enrichment_lookups": 41230,
                      "enrichment_cache_hits": 40118,
                      "enrichment_provider_calls": 1112,
                      "enrichment_skipped_low_value": 74320,
                      "unique_ips_seen": 1112,
                      "period_days": 30,
                      "cache_hit_rate": 0.973,
                      "unique_ip_ratio": 0.0087,
                      "provider_calls_per_1k_events": 8.66
                    }
                  },
                  "No events yet": {
                    "value": {
                      "events_ingested": 0,
                      "events_rejected": 0,
                      "enrichment_lookups": 0,
                      "enrichment_cache_hits": 0,
                      "enrichment_provider_calls": 0,
                      "enrichment_skipped_low_value": 0,
                      "unique_ips_seen": 0,
                      "period_days": 30,
                      "cache_hit_rate": null,
                      "unique_ip_ratio": null,
                      "provider_calls_per_1k_events": null
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Kunci API dengan cakupan terbatas telah kedaluwarsa. Hanya kunci yang kedaluwarsa yang menerima `401`; kunci yang hilang atau tidak valid menerima `403`.",
            "content": {
              "application/json": {
                "examples": {
                  "Expired key": {
                    "value": {
                      "detail": "This API key has expired."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "`x-api-key` tidak ada (kunci yang salah, dicabut, atau kedaluwarsa menghasilkan `401`), kunci dengan pembatasan cakupan tanpa `transactions: read`, kunci yang dibatasi pada alur kerja tertentu atau pada sesi yang disetujui (kunci semacam itu tidak pernah mengakses data pemantauan transaksi), atau permintaan dari luar allowlist IP milik kunci tersebut.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing or invalid API key": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Scoped key without access": {
                    "value": {
                      "detail": "This API key has no read access to transactions."
                    }
                  },
                  "Key limited to workflows or approved sessions": {
                    "value": {
                      "detail": "This API key only reaches sessions inside its workflow or status limits, so it can't use this endpoint."
                    }
                  },
                  "IP not allowed": {
                    "value": {
                      "detail": "This API key can't be used from this IP address."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Batas laju terlampaui: permintaan `GET` berbagi anggaran sebanyak 600 permintaan per menit per kunci API. Tunggu `Retry-After` detik, lalu coba lagi.",
            "headers": {
              "Retry-After": {
                "description": "Detik untuk menunggu sebelum mencoba lagi.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "example": 30
                }
              }
            },
            "content": {
              "application/json": {
                "examples": {
                  "Throttled": {
                    "value": {
                      "detail": "GET request rate limit exceeded. You can make up to 600 requests per minute."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/events/{event_uuid}/delete/": {
      "delete": {
        "summary": "Hapus event pemantauan",
        "description": "Hapus secara permanen satu event pemantauan beserta eksekusi aturan, catatan, dan tautan tag miliknya, misalnya event yang terkirim karena kesalahan. Setelah respons `204`, event tersebut hilang dari setiap operasi baca (pengambilan data mengembalikan `404`, serta tidak lagi muncul dalam daftar atau linimasa subjek), penghapusan ini tidak dapat dibatalkan, dan `event_id` miliknya bebas digunakan untuk event baru. Tidak terpengaruh: pengguna atau perusahaan yang menjadi rujukan event, kasus yang dibuka oleh suatu aturan, entri daftar yang ditambahkan oleh suatu aturan, serta skor dan status yang telah diterapkan ke event lain. Untuk menghapus semua hal tentang seseorang atau sebuah perusahaan, hapus pengguna atau perusahaan tersebut, yang juga akan menghapus event mereka. Kunci API dengan cakupan memerlukan `transactions: write`.",
        "operationId": "delete_monitoring_event",
        "x-didit-sdk": {
          "resource": "monitoring_events",
          "method": "delete",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Monitoring Events"
        ],
        "parameters": [
          {
            "name": "event_uuid",
            "in": "path",
            "required": true,
            "description": "Pengidentifikasi Didit untuk event tersebut (`event_uuid` dari respons pembuatan, batch, daftar, atau linimasa), bukan `event_id` Anda sendiri.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "11111111-2222-3333-4444-555555555555"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X DELETE 'https://verification.didit.me/v3/events/11111111-2222-3333-4444-555555555555/delete/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nclient.monitoring_events.delete(\n    \"11111111-2222-3333-4444-555555555555\",\n)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nawait didit.monitoringEvents.delete(\"11111111-2222-3333-4444-555555555555\");"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nif err := client.MonitoringEvents.Delete(ctx, \"11111111-2222-3333-4444-555555555555\"); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nclient.monitoringEvents().delete(\"11111111-2222-3333-4444-555555555555\");"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$didit->monitoringEvents->delete('11111111-2222-3333-4444-555555555555');"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.monitoring_events.delete(\"11111111-2222-3333-4444-555555555555\")"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nawait client.MonitoringEvents.DeleteAsync(\"11111111-2222-3333-4444-555555555555\");"
          }
        ],
        "responses": {
          "204": {
            "description": "Event telah dihapus. Tanpa body."
          },
          "401": {
            "description": "Kunci API dengan cakupan terbatas telah kedaluwarsa. Hanya kunci yang kedaluwarsa yang menerima `401`; kunci yang hilang atau tidak valid menerima `403`.",
            "content": {
              "application/json": {
                "examples": {
                  "Expired key": {
                    "value": {
                      "detail": "This API key has expired."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "`x-api-key` tidak ada (kunci yang salah, dicabut, atau kedaluwarsa menghasilkan `401`), kunci dengan pembatasan cakupan tanpa `transactions: write`, kunci yang dibatasi pada alur kerja tertentu atau pada sesi yang disetujui (kunci semacam itu tidak pernah mengakses data pemantauan transaksi), atau permintaan dari luar allowlist IP milik kunci tersebut.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing or invalid API key": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Scoped key without access": {
                    "value": {
                      "detail": "This API key has no write access to transactions."
                    }
                  },
                  "Key limited to workflows or approved sessions": {
                    "value": {
                      "detail": "This API key only reaches sessions inside its workflow or status limits, so it can't use this endpoint."
                    }
                  },
                  "IP not allowed": {
                    "value": {
                      "detail": "This API key can't be used from this IP address."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Tidak ada event dengan `event_uuid` ini di dalam aplikasi: event tidak pernah disimpan, telah dihapus, atau milik aplikasi lain. Segmen jalur yang bukan berupa UUID tidak cocok dengan rute dan juga mengembalikan `404`.",
            "content": {
              "application/json": {
                "examples": {
                  "Not found": {
                    "value": {
                      "detail": "No MonitoringEvent matches the given query."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Batas laju terlampaui: permintaan tulis (`POST`, `PATCH`, `DELETE`) berbagi anggaran sebanyak 300 permintaan per menit per kunci API. Tunggu `Retry-After` detik, lalu coba lagi.",
            "headers": {
              "Retry-After": {
                "description": "Detik untuk menunggu sebelum mencoba lagi.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "example": 30
                }
              }
            },
            "content": {
              "application/json": {
                "examples": {
                  "Throttled": {
                    "value": {
                      "detail": "Write request rate limit exceeded. You can make up to 300 requests per minute."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/session/{sessionId}/kyb/parties/{partyUuid}/regenerate/": {
      "post": {
        "summary": "Buat ulang sesi KYC pihak kunci",
        "description": "Berikan sesi KYC individu baru kepada pihak kunci dalam sesi Verifikasi Bisnis (KYB) setelah sesi sebelumnya dihapus atau kedaluwarsa sebelum orang tersebut memulainya, sehingga pemeriksaan pihak kunci dapat selesai kembali; jangan kirimkan isi permintaan. Ini berfungsi ketika sesi KYC pihak tersebut telah dihapus (`kyc_session_deleted: true`) atau kedaluwarsa sebelum orang tersebut memulainya (`Expired`, tidak pernah dimulai). Sesi yang masih berlangsung atau yang berakhir dengan status lain apa pun (`Approved`, `Declined`, `In Review`, `Abandoned`, ...) mengembalikan `409` kecuali jika telah dihapus. Pihak yang tidak pernah memilikinya atau pihak berupa perusahaan selalu mengembalikan `409`. Didit membuat sesi KYC baru yang di-hosting dengan alur kerja yang digunakan saat pihak tersebut diverifikasi (versi terbitan terbarunya) atau, jika tidak lagi diketahui, alur kerja yang ditetapkan pengaturan pihak kunci Anda untuk peran pihak tersebut, sehingga tautannya berlaku selama waktu kedaluwarsa sesi alur kerja KYC tersebut; Didit mengirimkan tautan tersebut melalui email kepada pihak tersebut jika email tercatat, mengosongkan `is_skipped`, dan menghitung ulang pemeriksaan pihak kunci serta status sesi bisnis. Kemudian Didit mengirimkan [webhook](https://docs.didit.me/id/integration/webhooks) `data.updated` untuk sesi bisnis dengan pemicu `console_key_people_regenerate`; untuk mengecualikan pihak tersebut sebagai gantinya, gunakan `PATCH /v3/session/{sessionId}/kyb/parties/{partyUuid}/`. Kunci API dengan pembatasan cakupan memerlukan `decisions: write`, dan tanpa `sessions: write` kunci tersebut menerima `kyc_session_url` sebagai `null`. Sesi yang dihapus memenuhi syarat meskipun orang tersebut telah memulai atau menyelesaikan verifikasi. Sesi yang diimpor tidak memenuhi syarat karena kedaluwarsa; sesi tersebut harus sudah dihapus.",
        "operationId": "post_v3_session_kyb_party_regenerate",
        "x-didit-sdk": {
          "resource": "sessions",
          "method": "regenerate_kyb_party",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Sessions"
        ],
        "parameters": [
          {
            "name": "sessionId",
            "in": "path",
            "required": true,
            "description": "UUID dari sesi induk Verifikasi Bisnis (KYB).",
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "33333333-4444-5555-6666-777777777777"
            }
          },
          {
            "name": "partyUuid",
            "in": "path",
            "required": true,
            "description": "UUID pihak kunci (`key_people_checks[].submitted.parties[].uuid` pada keputusan sesi bisnis). Harus dimiliki oleh sesi yang dirujuk oleh `sessionId`.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "0a3f1e2c-7c2f-4a1b-9d55-2f8d2a5d6b41"
            }
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://verification.didit.me/v3/session/33333333-4444-5555-6666-777777777777/kyb/parties/0a3f1e2c-7c2f-4a1b-9d55-2f8d2a5d6b41/regenerate/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.regenerate_kyb_party(\n    \"33333333-4444-5555-6666-777777777777\",\n    \"0a3f1e2c-7c2f-4a1b-9d55-2f8d2a5d6b41\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.regenerateKybParty(\n  \"33333333-4444-5555-6666-777777777777\",\n  \"0a3f1e2c-7c2f-4a1b-9d55-2f8d2a5d6b41\",\n);\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.RegenerateKYBParty(ctx, \"33333333-4444-5555-6666-777777777777\", \"0a3f1e2c-7c2f-4a1b-9d55-2f8d2a5d6b41\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().regenerateKybParty(\"33333333-4444-5555-6666-777777777777\", \"0a3f1e2c-7c2f-4a1b-9d55-2f8d2a5d6b41\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->sessions->regenerateKybParty('33333333-4444-5555-6666-777777777777', '0a3f1e2c-7c2f-4a1b-9d55-2f8d2a5d6b41');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.regenerate_kyb_party(\n  \"33333333-4444-5555-6666-777777777777\",\n  \"0a3f1e2c-7c2f-4a1b-9d55-2f8d2a5d6b41\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.RegenerateKybPartyAsync(\"33333333-4444-5555-6666-777777777777\", \"0a3f1e2c-7c2f-4a1b-9d55-2f8d2a5d6b41\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "Sesi KYC baru dibuat. Mengembalikan pihak yang diperbarui beserta sesi turunan barunya, yang kedaluwarsa setelah waktu kedaluwarsa sesi alur kerja KYC tersebut.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/KYBKeyPeopleParty"
                },
                "example": {
                  "uuid": "0a3f1e2c-7c2f-4a1b-9d55-2f8d2a5d6b41",
                  "entity_type": "person",
                  "source": "USER",
                  "name": "Jane Smith",
                  "first_name": "Jane",
                  "last_name": "Smith",
                  "company_name": null,
                  "registration_number": null,
                  "email": "user@example.com",
                  "nationality": "GB",
                  "phone_number": null,
                  "date_of_birth": "1980-05-04",
                  "position": "Director",
                  "custom_fields": {},
                  "is_active": true,
                  "is_skipped": false,
                  "requires_verification": true,
                  "roles": [
                    {
                      "role": "director",
                      "ownership_percent": null,
                      "voting_percent": null
                    }
                  ],
                  "kyc_session_id": "55555555-6666-7777-8888-999999999999",
                  "kyc_session_status": "Not Started",
                  "kyc_session_url": "https://verify.didit.me/session/abc123def456",
                  "kyc_session_deleted": false,
                  "kyb_sub_session_id": null,
                  "kyb_sub_session_status": null,
                  "kyb_sub_session_url": null,
                  "kyb_sub_session_deleted": false,
                  "verification_workflow_type": "kyc",
                  "verification_workflow_id": "12121212-3434-5656-7878-909090909090",
                  "verification_workflow_label": "Key People KYC",
                  "verification_workflow_features": [
                    {
                      "feature": "ID_VERIFICATION",
                      "status": "Not Finished"
                    },
                    {
                      "feature": "LIVENESS",
                      "status": "Not Finished"
                    },
                    {
                      "feature": "AML",
                      "status": "Not Finished"
                    }
                  ],
                  "didit_internal_id": null
                }
              }
            }
          },
          "401": {
            "description": "Kunci API dengan cakupan terbatas telah kedaluwarsa. Ini satu-satunya kasus yang mengembalikan `401`: kunci yang hilang, tidak valid, atau dicabut mengembalikan `403`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "Pesan kesalahan yang mudah dibaca manusia."
                    }
                  }
                },
                "examples": {
                  "Expired key": {
                    "summary": "Tanggal kedaluwarsa kunci telah lewat",
                    "value": {
                      "detail": "This API key has expired."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Kegagalan autentikasi atau otorisasi. Kunci yang hilang mengembalikan `403`, begitu juga dengan kunci dari aplikasi lain, kunci dengan cakupan tanpa izin yang dibutuhkan endpoint ini, dan permintaan dari luar daftar izin IP kunci tersebut; kunci yang salah, dicabut, atau kedaluwarsa mengembalikan `401`. Bedakan kegagalan tersebut berdasarkan `detail`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "Pesan kesalahan yang mudah dibaca manusia."
                    }
                  }
                },
                "examples": {
                  "Missing or invalid credentials": {
                    "summary": "Tidak ada header x-api-key, atau kunci gagal divalidasi",
                    "value": {
                      "detail": "Authentication credentials were not provided or are invalid."
                    }
                  },
                  "Other application": {
                    "summary": "Kunci valid milik aplikasi yang berbeda dari sesi",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Scoped key without decisions write": {
                    "summary": "Kunci ber-scope tidak memiliki decisions: write",
                    "value": {
                      "detail": "This API key has no write access to decisions."
                    }
                  },
                  "IP not allowed": {
                    "summary": "Permintaan dari luar daftar izin IP kunci",
                    "value": {
                      "detail": "This API key can't be used from this IP address."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Sesi tidak ada, telah dihapus, atau berada di luar batas kunci dengan cakupan terbatas; tidak ada pihak dengan UUID ini yang ada di aplikasi Anda; atau pihak tersebut milik sesi lain. Setiap kasus memiliki `detail`-nya sendiri. Pencarian sesi berjalan sebelum pemeriksaan kredensial, sehingga `sessionId` yang tidak dikenal mengembalikan `404` bahkan tanpa kunci yang valid.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "Pesan kesalahan yang mudah dibaca manusia."
                    }
                  }
                },
                "examples": {
                  "Unknown session": {
                    "summary": "Tidak ada sesi dengan ID ini, atau telah dihapus",
                    "value": {
                      "detail": "Not found."
                    }
                  },
                  "Outside key limits": {
                    "summary": "Sesi berada di luar alur kerja atau batas yang hanya berlaku untuk sesi yang disetujui milik kunci dengan cakupan terbatas",
                    "value": {
                      "detail": "Session not found."
                    }
                  },
                  "Unknown party": {
                    "summary": "Tidak ada pihak dengan UUID ini di aplikasi Anda",
                    "value": {
                      "detail": "No BusinessParty matches the given query."
                    }
                  },
                  "Party of another session": {
                    "summary": "partyUuid ada tetapi milik sesi yang berbeda",
                    "value": {
                      "detail": "Party does not belong to the given session."
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "Pihak tersebut tidak memiliki sesi KYC yang memenuhi syarat untuk diganti. Kecuali dihapus, sesi yang masih berlangsung atau yang berakhir dengan status lain (`Approved`, `Declined`, `In Review`, `Abandoned`, ...) tidak dapat dibuat ulang. Pihak yang tidak pernah memilikinya atau pihak perusahaan juga mengembalikan `409`. Sesi yang memenuhi syarat dihapus atau kedaluwarsa sebelum orang tersebut memulainya. Sesi yang dihapus tetap memenuhi syarat meskipun orang tersebut telah memulai atau menyelesaikan verifikasi. Sesi yang diimpor tidak memenuhi syarat melalui kedaluwarsa; sesi tersebut harus sudah dihapus. Buat percabangan berdasarkan `code`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "detail",
                    "code"
                  ],
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "Pesan kesalahan yang mudah dibaca manusia."
                    },
                    "code": {
                      "type": "string",
                      "enum": [
                        "kyb_party_kyc_session_not_deleted"
                      ],
                      "description": "Kode error stabil yang dapat dibaca mesin."
                    }
                  }
                },
                "example": {
                  "detail": "This party's KYC session is still live (it has neither been deleted nor expired without starting), so it cannot be regenerated.",
                  "code": "kyb_party_kyc_session_not_deleted"
                }
              }
            }
          },
          "429": {
            "description": "Batas laju terlampaui: 300 permintaan penulisan (POST, PATCH, DELETE) per menit per kunci API. Tunggu selama `Retry-After` detik sebelum mencoba lagi; header `X-RateLimit-*` menunjukkan anggaran tersebut.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "Pesan kesalahan yang mudah dibaca manusia."
                    }
                  }
                },
                "examples": {
                  "Rate limited": {
                    "summary": "Anggaran untuk menit saat ini habis",
                    "value": {
                      "detail": "Write request rate limit exceeded. You can make up to 300 requests per minute."
                    }
                  }
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Detik untuk menunggu sebelum mencoba lagi.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "example": 30
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/transactions/{transaction_id}/notes/": {
      "get": {
        "summary": "Daftar catatan transaksi",
        "description": "Mencantumkan daftar catatan pada satu transaksi yang dipantau, yang terbaru lebih dahulu (`created_at` menurun): catatan yang Anda tambahkan melalui API, catatan dan perubahan status yang dibuat peninjau di Konsol, serta catatan yang ditambahkan Didit secara otomatis (tindakan `add_note` aturan, atau masalah saat membuat sesi verifikasi tindakan pengguna), yang memuat `actor_name` `Rule Engine`. `metadata` membedakan jenis-jenis catatan.\n\nDipaginasi dengan `limit` dan `offset`. `count` bersifat persis hingga 100 dan dibatasi pada 100 di atasnya, jadi ikuti `next` hingga bernilai `null` alih-alih menghitung halaman dari `count`. Ini adalah operasi baca tanpa efek samping.\n\nKunci API dengan pembatasan cakupan memerlukan `transactions: read`; kunci yang terbatas pada beberapa alur kerja atau sesi yang disetujui tidak dapat memanggil endpoint ini. Peninjau melihat daftar yang sama di bawah **Notes** pada [detail transaksi](https://docs.didit.me/id/transaction-monitoring/console#detail-transaksi).",
        "operationId": "list_transaction_notes",
        "x-didit-sdk": {
          "resource": "transactions.notes",
          "method": "list",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Transactions"
        ],
        "parameters": [
          {
            "name": "transaction_id",
            "in": "path",
            "required": true,
            "description": "UUID transaksi Didit: `uuid` yang dikembalikan oleh `POST /v3/transactions/` dan `GET /v3/transactions/`. `txn_id` Anda sendiri tidak diterima.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "abcdef12-3456-7890-abcd-ef1234567890"
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 50,
              "minimum": 1,
              "maximum": 1000000
            },
            "description": "Jumlah catatan per halaman. Default-nya 50. Nilai yang bukan bilangan bulat positif akan kembali ke 50; nilai di atas 1000000 mengembalikan `400`."
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 0,
              "minimum": 0,
              "maximum": 1000000
            },
            "description": "Posisi berbasis nol dari catatan pertama yang dikembalikan. Sebaiknya ikuti `next`. Nilai yang bukan bilangan bulat akan kembali ke 0; nilai di atas 1000000 mengembalikan `400`."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/transactions/abcdef12-3456-7890-abcd-ef1234567890/notes/?limit=50' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nfor item in client.transactions.notes.list(\n    \"abcdef12-3456-7890-abcd-ef1234567890\",\n):\n    print(item)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nfor await (const item of didit.transactions.notes.list(\"abcdef12-3456-7890-abcd-ef1234567890\")) {\n  console.log(item);\n}"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\niter := client.Transactions.Notes.ListAutoPaging(ctx, \"abcdef12-3456-7890-abcd-ef1234567890\", didit.TransactionsNotesListParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nfor (var item : client.transactions().notes().list(\"abcdef12-3456-7890-abcd-ef1234567890\")) {\n    System.out.println(item);\n}"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\nforeach ($didit->transactions->notes->list('abcdef12-3456-7890-abcd-ef1234567890') as $item) {\n    print_r($item->toArray());\n}"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.transactions.notes.list(\"abcdef12-3456-7890-abcd-ef1234567890\").auto_paging_each do |item|\n  puts item.to_h\nend"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.Transactions.Notes.ListAsync(\"abcdef12-3456-7890-abcd-ef1234567890\"))\n{\n    Console.WriteLine(JsonSerializer.Serialize(item));\n}"
          }
        ],
        "responses": {
          "200": {
            "description": "Satu halaman catatan, yang terbaru lebih dulu.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "count",
                    "next",
                    "previous",
                    "results"
                  ],
                  "properties": {
                    "count": {
                      "type": "integer",
                      "description": "Jumlah catatan pada transaksi: tepat hingga 100, dibatasi maksimal 100 di atasnya. Ikuti `next` alih-alih menghitung halaman darinya."
                    },
                    "next": {
                      "type": "string",
                      "format": "uri",
                      "nullable": true,
                      "description": "URL absolut halaman berikutnya, atau `null` di halaman terakhir."
                    },
                    "previous": {
                      "type": "string",
                      "format": "uri",
                      "nullable": true,
                      "description": "URL absolut halaman sebelumnya, atau `null` di halaman pertama."
                    },
                    "results": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/TransactionNote"
                      }
                    }
                  }
                },
                "examples": {
                  "API, Console and rule notes": {
                    "value": {
                      "count": 3,
                      "next": null,
                      "previous": null,
                      "results": [
                        {
                          "uuid": "c1111111-2222-4333-8444-555555555555",
                          "note": "Customer confirmed the withdrawal by phone.",
                          "actor_email": null,
                          "actor_name": null,
                          "metadata": {
                            "mentioned_emails": [
                              "analyst@example.com"
                            ]
                          },
                          "created_at": "2026-10-16T10:05:12.481203Z"
                        },
                        {
                          "uuid": "c2222222-3333-4444-8555-666666666666",
                          "note": "Status changed from IN_REVIEW to APPROVED. Reason: Source of funds verified",
                          "actor_email": "reviewer@example.com",
                          "actor_name": "Alex Reviewer",
                          "metadata": {
                            "type": "status_change",
                            "previous_status": "IN_REVIEW",
                            "new_status": "APPROVED",
                            "reason_code": "SOF_VERIFIED",
                            "reason_label": "Source of funds verified"
                          },
                          "created_at": "2026-10-15T17:22:40.103911Z"
                        },
                        {
                          "uuid": "c3333333-4444-4555-8666-777777777777",
                          "note": "Large withdrawal to a new wallet: check the source of funds.",
                          "actor_email": null,
                          "actor_name": "Rule Engine",
                          "metadata": {
                            "rule_uuid": "d1111111-2222-4333-8444-555555555555",
                            "source": "rule_action"
                          },
                          "created_at": "2026-10-15T08:42:12.004518Z"
                        }
                      ]
                    }
                  },
                  "No notes yet": {
                    "value": {
                      "count": 0,
                      "next": null,
                      "previous": null,
                      "results": []
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "`limit` atau `offset` berada di atas 1000000. Bagian body adalah array JSON berisi pesan, bukan objek.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                },
                "examples": {
                  "Limit too large": {
                    "value": [
                      "limit must not exceed 1000000."
                    ]
                  },
                  "Offset too large": {
                    "value": [
                      "offset must not exceed 1000000."
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Kunci API telah kedaluwarsa. Hanya kunci yang dibuat dengan tanggal kedaluwarsa yang dapat kedaluwarsa; setelah tanggal tersebut, setiap permintaan dengannya menghasilkan respons `401`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Expired key": {
                    "value": {
                      "detail": "This API key has expired."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Permintaan tidak diizinkan. Kunci yang tidak ada akan mendapatkan pesan umum; kunci yang salah, dicabut, atau kedaluwarsa akan mendapatkan `401`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Missing or invalid key": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Scoped key without transactions read": {
                    "value": {
                      "detail": "This API key has no read access to transactions."
                    }
                  },
                  "Key limited to workflows or approved sessions": {
                    "value": {
                      "detail": "This API key only reaches sessions inside its workflow or status limits, so it can't use this endpoint."
                    }
                  },
                  "Outside the key's IP list": {
                    "value": {
                      "detail": "This API key can't be used from this IP address."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Tidak ada transaksi dengan UUID ini di aplikasi tersebut (tidak pernah dibuat, dihapus, atau dimiliki oleh aplikasi lain). `transaction_id` yang bukan UUID tidak mencapai API: permintaan ini mengembalikan halaman HTML `404`, bukan body JSON ini.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Not found": {
                    "value": {
                      "detail": "No Transaction matches the given query."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Lebih dari 600 permintaan GET per menit dengan kunci API ini. Tunggu selama jumlah detik di `Retry-After`, lalu coba lagi.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Throttled": {
                    "value": {
                      "detail": "GET request rate limit exceeded. You can make up to 600 requests per minute."
                    }
                  }
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Detik hingga jendela satu menit saat ini direset.",
                "schema": {
                  "type": "integer",
                  "example": 23
                }
              },
              "X-RateLimit-Limit": {
                "description": "Permintaan yang diizinkan per menit dalam anggaran ini.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Permintaan tersisa dalam jendela saat ini.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Waktu Unix saat jendela direset.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      },
      "post": {
        "summary": "Buat catatan transaksi",
        "description": "Tambahkan catatan teks biasa ke timeline peninjauan transaksi yang dipantau, tempat peninjau Console melihatnya. Catatan adalah konteks, bukan keputusan: `status`, `score`, dan alert transaksi tidak berubah, tidak ada webhook yang dikirim, dan tidak ada biaya yang ditagih. `activities` transaksi akan mendapatkan entri `TRANSACTION_NOTE_ADDED`.\n\nCatatan yang dibuat dengan kunci API tidak memiliki pembuat: `actor_email` dan `actor_name` bernilai `null`, jadi sertakan pembuatnya di dalam teks jika Anda membutuhkannya. Setiap alamat di `mentioned_emails` harus milik anggota organisasi Anda, jika tidak seluruh permintaan akan gagal dengan `400`; sebutan disimpan dalam huruf kecil dan di-deduplikasi, dan endpoint ini tidak memberi tahu anggota yang disebutkan.\n\nSetiap panggilan membuat catatan baru, sehingga mencoba lagi permintaan yang waktu habis dapat menambahkannya dua kali: buat daftar catatan sebelum mencoba lagi. Tidak ada endpoint API untuk mengedit atau menghapus catatan. Kunci API dengan cakupan memerlukan `transactions: write`; kunci yang dibatasi pada beberapa alur kerja atau pada sesi yang disetujui tidak dapat memanggil endpoint ini.",
        "operationId": "create_transaction_note",
        "x-didit-sdk": {
          "resource": "transactions.notes",
          "method": "create",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Transactions"
        ],
        "parameters": [
          {
            "name": "transaction_id",
            "in": "path",
            "required": true,
            "description": "UUID transaksi Didit: `uuid` yang dikembalikan oleh `POST /v3/transactions/` dan `GET /v3/transactions/`. `txn_id` Anda sendiri tidak diterima.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "abcdef12-3456-7890-abcd-ef1234567890"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "note"
                ],
                "properties": {
                  "note": {
                    "type": "string",
                    "minLength": 1,
                    "description": "Catatan teks biasa. Spasi di awal dan akhir akan dipangkas dan catatan kosong akan ditolak. Tidak ada batas panjang."
                  },
                  "mentioned_emails": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "format": "email"
                    },
                    "default": [],
                    "description": "Email anggota organisasi Anda yang akan disebutkan. Masing-masing harus berupa email valid dari anggota organisasi."
                  }
                }
              },
              "examples": {
                "Note with a mention": {
                  "value": {
                    "note": "Customer confirmed the withdrawal by phone.",
                    "mentioned_emails": [
                      "analyst@example.com"
                    ]
                  }
                },
                "Plain note": {
                  "value": {
                    "note": "Source of funds document requested by email."
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://verification.didit.me/v3/transactions/abcdef12-3456-7890-abcd-ef1234567890/notes/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"note\": \"Customer confirmed the withdrawal by phone.\", \"mentioned_emails\": [\"analyst@example.com\"]}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.transactions.notes.create(\n    \"abcdef12-3456-7890-abcd-ef1234567890\",\n    note=\"Customer confirmed the withdrawal by phone.\",\n    mentioned_emails=[\"analyst@example.com\"],\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.transactions.notes.create(\"abcdef12-3456-7890-abcd-ef1234567890\", {\n  note: \"Customer confirmed the withdrawal by phone.\",\n  mentioned_emails: [\"analyst@example.com\"],\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Transactions.Notes.Create(ctx, \"abcdef12-3456-7890-abcd-ef1234567890\", didit.TransactionsNotesCreateParams{\n\tNote:            \"Customer confirmed the withdrawal by phone.\",\n\tMentionedEmails: didit.Some([]string{\"analyst@example.com\"}),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.List;\nimport me.didit.Didit;\nimport me.didit.types.TransactionsNotesCreateParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.transactions().notes().create(\"abcdef12-3456-7890-abcd-ef1234567890\", TransactionsNotesCreateParams.builder()\n        .note(\"Customer confirmed the withdrawal by phone.\")\n        .mentionedEmails(List.of(\"analyst@example.com\"))\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->transactions->notes->create('abcdef12-3456-7890-abcd-ef1234567890', [\n    'note' => 'Customer confirmed the withdrawal by phone.',\n    'mentioned_emails' => ['analyst@example.com'],\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.transactions.notes.create(\n  \"abcdef12-3456-7890-abcd-ef1234567890\",\n  note: \"Customer confirmed the withdrawal by phone.\",\n  mentioned_emails: [\"analyst@example.com\"]\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Transactions.Notes.CreateAsync(\"abcdef12-3456-7890-abcd-ef1234567890\", new TransactionsNotesCreateParams\n{\n    Note = \"Customer confirmed the withdrawal by phone.\",\n    MentionedEmails = new string[] { \"analyst@example.com\" },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "201": {
            "description": "Catatan berhasil dibuat.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TransactionNote"
                },
                "examples": {
                  "Created": {
                    "value": {
                      "uuid": "c1111111-2222-4333-8444-555555555555",
                      "note": "Customer confirmed the withdrawal by phone.",
                      "actor_email": null,
                      "actor_name": null,
                      "metadata": {
                        "mentioned_emails": [
                          "analyst@example.com"
                        ]
                      },
                      "created_at": "2026-10-16T10:05:12.481203Z"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Isi permintaan tidak valid: `note` tidak ada, null, atau kosong, alamat tidak valid di `mentioned_emails` (kesalahan diberi kunci berdasarkan posisi daftar), atau alamat yang disebut bukan anggota organisasi Anda. Tidak ada yang dibuat.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Error kolom dengan kunci berdasarkan nama kolom.",
                  "additionalProperties": {}
                },
                "examples": {
                  "Missing note": {
                    "value": {
                      "note": [
                        "This field is required."
                      ]
                    }
                  },
                  "Blank note": {
                    "value": {
                      "note": [
                        "This field may not be blank."
                      ]
                    }
                  },
                  "Invalid email": {
                    "value": {
                      "mentioned_emails": {
                        "0": [
                          "Enter a valid email address."
                        ]
                      }
                    }
                  },
                  "Not an organization member": {
                    "value": {
                      "mentioned_emails": [
                        "Mentioned users must belong to this organization and have access to this application."
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Kunci API telah kedaluwarsa. Hanya kunci yang dibuat dengan tanggal kedaluwarsa yang dapat kedaluwarsa; setelah tanggal tersebut, setiap permintaan dengannya menghasilkan respons `401`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Expired key": {
                    "value": {
                      "detail": "This API key has expired."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Permintaan tidak diizinkan. Kunci yang tidak ada akan mendapatkan pesan umum; kunci yang salah, dicabut, atau kedaluwarsa akan mendapatkan `401`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Missing or invalid key": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Scoped key without transactions write": {
                    "value": {
                      "detail": "This API key has no write access to transactions."
                    }
                  },
                  "Key limited to workflows or approved sessions": {
                    "value": {
                      "detail": "This API key only reaches sessions inside its workflow or status limits, so it can't use this endpoint."
                    }
                  },
                  "Outside the key's IP list": {
                    "value": {
                      "detail": "This API key can't be used from this IP address."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Tidak ada transaksi dengan UUID ini di aplikasi tersebut (tidak pernah dibuat, dihapus, atau dimiliki oleh aplikasi lain). `transaction_id` yang bukan UUID tidak mencapai API: permintaan ini mengembalikan halaman HTML `404`, bukan body JSON ini.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Not found": {
                    "value": {
                      "detail": "No Transaction matches the given query."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Lebih dari 300 permintaan tulis per menit dengan kunci API ini. Tunggu selama jumlah detik di `Retry-After`, lalu coba lagi.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Throttled": {
                    "value": {
                      "detail": "Write request rate limit exceeded. You can make up to 300 requests per minute."
                    }
                  }
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Detik hingga jendela satu menit saat ini direset.",
                "schema": {
                  "type": "integer",
                  "example": 23
                }
              },
              "X-RateLimit-Limit": {
                "description": "Permintaan yang diizinkan per menit dalam anggaran ini.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Permintaan tersisa dalam jendela saat ini.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Waktu Unix saat jendela direset.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/transactions/{transaction_id}/related/": {
      "get": {
        "summary": "Mencantumkan transaksi terkait",
        "description": "Daftar transaksi lain di aplikasi Anda yang melibatkan orang atau perusahaan yang sama dengan transaksi ini. Transaksi terkait ketika ada salah satu pihaknya, dalam peran apa pun, memiliki `vendor_data` yang sama dengan salah satu pihak transaksi ini. Transaksi itu sendiri tidak pernah dikembalikan, dan pihak tanpa `vendor_data` diabaikan: jika tidak ada pihak transaksi ini yang memilikinya, hasilnya selalu kosong.\n\nHasil menggunakan bentuk ringkasan `GET /v3/transactions/`, terbaru terlebih dahulu (`txn_date`, lalu `created_at`). Dipaginasi dengan `limit` dan `offset`; `count` tepat hingga 100 dan dibatasi pada 100 di atasnya, jadi ikuti `next` hingga bernilai `null`.\n\nKunci API dengan cakupan memerlukan `transactions: read`; kunci yang dibatasi untuk beberapa alur kerja atau ke sesi yang disetujui tidak dapat memanggil endpoint ini. Kirim `vendor_data` yang sama untuk orang atau perusahaan yang sama pada setiap [transaksi](https://docs.didit.me/id/transaction-monitoring/transactions#subjek-dan-pihak-lawan) agar daftar ini lengkap.",
        "operationId": "list_related_transactions",
        "x-didit-sdk": {
          "resource": "transactions",
          "method": "list_related",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Transactions"
        ],
        "parameters": [
          {
            "name": "transaction_id",
            "in": "path",
            "required": true,
            "description": "UUID transaksi Didit: `uuid` yang dikembalikan oleh `POST /v3/transactions/` dan `GET /v3/transactions/`. `txn_id` Anda sendiri tidak diterima.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "abcdef12-3456-7890-abcd-ef1234567890"
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 50,
              "minimum": 1,
              "maximum": 1000000
            },
            "description": "Jumlah transaksi per halaman. Default-nya 50. Nilai yang bukan bilangan bulat positif akan kembali ke 50; nilai di atas 1000000 mengembalikan `400`."
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 0,
              "minimum": 0,
              "maximum": 1000000
            },
            "description": "Posisi berbasis nol dari transaksi pertama yang dikembalikan. Sebaiknya ikuti `next`. Nilai yang bukan bilangan bulat akan kembali ke 0; nilai di atas 1000000 mengembalikan `400`."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/transactions/abcdef12-3456-7890-abcd-ef1234567890/related/?limit=50' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nfor item in client.transactions.list_related(\n    \"abcdef12-3456-7890-abcd-ef1234567890\",\n):\n    print(item)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nfor await (const item of didit.transactions.listRelated(\"abcdef12-3456-7890-abcd-ef1234567890\")) {\n  console.log(item);\n}"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\niter := client.Transactions.ListRelatedAutoPaging(ctx, \"abcdef12-3456-7890-abcd-ef1234567890\", didit.TransactionsListRelatedParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nfor (var item : client.transactions().listRelated(\"abcdef12-3456-7890-abcd-ef1234567890\")) {\n    System.out.println(item);\n}"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\nforeach ($didit->transactions->listRelated('abcdef12-3456-7890-abcd-ef1234567890') as $item) {\n    print_r($item->toArray());\n}"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.transactions.list_related(\"abcdef12-3456-7890-abcd-ef1234567890\").auto_paging_each do |item|\n  puts item.to_h\nend"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.Transactions.ListRelatedAsync(\"abcdef12-3456-7890-abcd-ef1234567890\"))\n{\n    Console.WriteLine(JsonSerializer.Serialize(item));\n}"
          }
        ],
        "responses": {
          "200": {
            "description": "Satu halaman transaksi terkait, yang terbaru lebih dulu.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "count",
                    "next",
                    "previous",
                    "results"
                  ],
                  "properties": {
                    "count": {
                      "type": "integer",
                      "description": "Jumlah transaksi terkait: tepat hingga 100, dibatasi maksimal 100 di atasnya. Ikuti `next` alih-alih menghitung halaman darinya."
                    },
                    "next": {
                      "type": "string",
                      "format": "uri",
                      "nullable": true,
                      "description": "URL absolut halaman berikutnya, atau `null` di halaman terakhir."
                    },
                    "previous": {
                      "type": "string",
                      "format": "uri",
                      "nullable": true,
                      "description": "URL absolut halaman sebelumnya, atau `null` di halaman pertama."
                    },
                    "results": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/TransactionSummary"
                      }
                    }
                  }
                },
                "examples": {
                  "One related transaction": {
                    "value": {
                      "count": 1,
                      "next": null,
                      "previous": null,
                      "results": [
                        {
                          "uuid": "abcdef99-3456-4890-abcd-ef1234567890",
                          "transaction_number": 4087,
                          "txn_id": "your-txn-2026-10-02-017",
                          "transaction_type": "finance",
                          "action_type": "deposit",
                          "status": "APPROVED",
                          "source": "LIVE",
                          "direction": "INBOUND",
                          "amount": "250",
                          "currency": "EUR",
                          "currency_type": "fiat",
                          "preferred_currency_amount": "270.08",
                          "preferred_currency_code": "USD",
                          "payment_details": "Card top-up",
                          "txn_date": "2026-10-02T14:10:00Z",
                          "created_at": "2026-10-02T14:10:03.512244Z",
                          "score": 12,
                          "severity": "LOW",
                          "decision_reason_code": null,
                          "decision_reason_label": null,
                          "tags": [],
                          "subject_name": "Maria Garcia",
                          "subject_vendor_data": "user-12345",
                          "subject_type": "user",
                          "subject_uuid": "e1111111-2222-4333-8444-555555555555",
                          "counterparty_name": null,
                          "counterparty_vendor_data": null,
                          "counterparty_country": null,
                          "subject_country": "ESP",
                          "assigned_to_name": null,
                          "travel_rule_status": null,
                          "application_id": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee",
                          "application_name": "Production app",
                          "organization_id": "11111111-2222-3333-4444-555555555555",
                          "organization_name": "Example Org"
                        }
                      ]
                    }
                  },
                  "No party has vendor_data": {
                    "value": {
                      "count": 0,
                      "next": null,
                      "previous": null,
                      "results": []
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "`limit` atau `offset` berada di atas 1000000. Bagian body adalah array JSON berisi pesan, bukan objek.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                },
                "examples": {
                  "Limit too large": {
                    "value": [
                      "limit must not exceed 1000000."
                    ]
                  },
                  "Offset too large": {
                    "value": [
                      "offset must not exceed 1000000."
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Kunci API telah kedaluwarsa. Hanya kunci yang dibuat dengan tanggal kedaluwarsa yang dapat kedaluwarsa; setelah tanggal tersebut, setiap permintaan dengannya menghasilkan respons `401`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Expired key": {
                    "value": {
                      "detail": "This API key has expired."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Permintaan tidak diizinkan. Kunci yang tidak ada akan mendapatkan pesan umum; kunci yang salah, dicabut, atau kedaluwarsa akan mendapatkan `401`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Missing or invalid key": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Scoped key without transactions read": {
                    "value": {
                      "detail": "This API key has no read access to transactions."
                    }
                  },
                  "Key limited to workflows or approved sessions": {
                    "value": {
                      "detail": "This API key only reaches sessions inside its workflow or status limits, so it can't use this endpoint."
                    }
                  },
                  "Outside the key's IP list": {
                    "value": {
                      "detail": "This API key can't be used from this IP address."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Tidak ada transaksi dengan UUID ini di aplikasi tersebut (tidak pernah dibuat, dihapus, atau dimiliki oleh aplikasi lain). `transaction_id` yang bukan UUID tidak mencapai API: permintaan ini mengembalikan halaman HTML `404`, bukan body JSON ini.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Not found": {
                    "value": {
                      "detail": "No Transaction matches the given query."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Lebih dari 600 permintaan GET per menit dengan kunci API ini. Tunggu selama jumlah detik di `Retry-After`, lalu coba lagi.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Throttled": {
                    "value": {
                      "detail": "GET request rate limit exceeded. You can make up to 600 requests per minute."
                    }
                  }
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Detik hingga jendela satu menit saat ini direset.",
                "schema": {
                  "type": "integer",
                  "example": 23
                }
              },
              "X-RateLimit-Limit": {
                "description": "Permintaan yang diizinkan per menit dalam anggaran ini.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Permintaan tersisa dalam jendela saat ini.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Waktu Unix saat jendela direset.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/businesses/{business_session_id}/pdf/": {
      "get": {
        "summary": "Unduh laporan PDF sesi bisnis",
        "description": "Render laporan PDF dari satu sesi Verifikasi Bisnis (KYB): data registri perusahaan, pihak kunci dan pemilik manfaat, dokumen, hasil AML, dan fitur alur kerja lainnya, ditambah tag dan aktivitas peninjauan sesi tersebut. Dengan kustomisasi White Label yang aktif, laporan akan memuat logo dan URL kebijakan privasi Anda. Isi respons berupa PDF itu sendiri (`application/pdf`), bukan JSON.\n\nSesi harus berstatus `Approved`, `Declined`, atau `In Review`; status lainnya akan mengembalikan `403`, jadi tunggu [webhook](https://docs.didit.me/id/integration/webhooks) `status.updated` terlebih dahulu. Laporan di-render pada setiap panggilan dan tidak ada biaya yang ditagihkan, jadi simpan file tersebut alih-alih mengambilnya berulang kali. `GET /v3/session/{sessionId}/generate-pdf/` me-render jenis laporan yang sama hanya dengan ID sesi.\n\nLaporan PDF dihitung sebagai media: kunci API ber-scope memerlukan `businesses: read` dan `media: read`, dan kunci yang dibatasi ke beberapa alur kerja atau ke sesi yang disetujui tidak dapat memanggilnya.",
        "operationId": "get_business_session_pdf",
        "x-didit-sdk": {
          "resource": "businesses",
          "method": "generate_session_pdf",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Businesses"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID organisasi.",
            "example": "11111111-2222-3333-4444-555555555555"
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID aplikasi. Harus berupa aplikasi pemilik kunci API tersebut: kunci yang digunakan pada aplikasi lain mana pun akan mendapatkan `403`.",
            "example": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee"
          },
          {
            "name": "business_session_id",
            "in": "path",
            "required": true,
            "description": "`session_id` dari sesi Verifikasi Bisnis (KYB), seperti yang dikembalikan saat sesi dibuat. Sesi dari aplikasi lain mengembalikan `404`.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "22222222-3333-4444-5555-666666666666"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl --fail -X GET 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/businesses/22222222-3333-4444-5555-666666666666/pdf/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  --output business_report.pdf"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\ncontent = client.businesses.generate_session_pdf(\n    \"22222222-3333-4444-5555-666666666666\",\n)\nwith open(\"download.pdf\", \"wb\") as file:\n    file.write(content)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import { writeFile } from \"node:fs/promises\";\nimport Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst content = await didit.businesses.generateSessionPdf(\"22222222-3333-4444-5555-666666666666\");\nawait writeFile(\"download.pdf\", Buffer.from(await content.arrayBuffer()));"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresp, err := client.Businesses.GenerateSessionPDF(ctx, \"22222222-3333-4444-5555-666666666666\")\nif err != nil {\n\tlog.Fatal(err)\n}\ndefer resp.Body.Close()\nfile, err := os.Create(\"download.pdf\")\nif err != nil {\n\tlog.Fatal(err)\n}\ndefer file.Close()\nif _, err := io.Copy(file, resp.Body); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.nio.file.Path;\nimport me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nclient.businesses().generateSessionPdf(\"22222222-3333-4444-5555-666666666666\")\n        .writeTo(Path.of(\"download.pdf\"));"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$content = $didit->businesses->generateSessionPdf('22222222-3333-4444-5555-666666666666');\n$content->saveTo('download.pdf');"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\ncontent = didit.businesses.generate_session_pdf(\"22222222-3333-4444-5555-666666666666\")\nFile.binwrite(\"download.pdf\", content)"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar content = await client.Businesses.GenerateSessionPdfAsync(\"22222222-3333-4444-5555-666666666666\");\nawait content.SaveToAsync(\"download.pdf\");"
          }
        ],
        "responses": {
          "200": {
            "description": "PDF hasil render, dikembalikan langsung sebagai biner `application/pdf`.",
            "headers": {
              "Content-Disposition": {
                "description": "Selalu `attachment; filename=business_{business_session_id}.pdf`.",
                "schema": {
                  "type": "string",
                  "example": "attachment; filename=business_22222222-3333-4444-5555-666666666666.pdf"
                }
              }
            },
            "content": {
              "application/pdf": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "401": {
            "description": "Kunci API telah kedaluwarsa. Hanya kunci yang dibuat dengan tanggal kedaluwarsa yang dapat kedaluwarsa; setelah tanggal tersebut, setiap permintaan dengannya menghasilkan respons `401`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Expired key": {
                    "value": {
                      "detail": "This API key has expired."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Permintaan tidak diizinkan atau sesi belum selesai. Baca `detail`: sesi yang bukan `Approved`, `Declined`, atau `In Review`, kunci API tidak ada (kunci yang salah, dicabut, atau kedaluwarsa mendapatkan `401`), `application_id` yang bukan merupakan aplikasi milik kunci tersebut, kunci dengan pembatasan cakupan tanpa `media: read` atau `businesses: read`, kunci yang dibatasi untuk alur kerja atau sesi yang disetujui, atau permintaan dari luar daftar IP milik kunci tersebut.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Session not finished": {
                    "value": {
                      "detail": "You can only generate a PDF for sessions in review, declined or approved."
                    }
                  },
                  "Missing or invalid key": {
                    "value": {
                      "detail": "Authentication credentials were not provided or are invalid."
                    }
                  },
                  "Another application": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Scoped key without media read": {
                    "value": {
                      "detail": "This API key has no read access to media."
                    }
                  },
                  "Scoped key without businesses read": {
                    "value": {
                      "detail": "This API key has no read access to companies."
                    }
                  },
                  "Key limited to workflows or approved sessions": {
                    "value": {
                      "detail": "This API key only reaches sessions inside its workflow or status limits, so it can't use this endpoint."
                    }
                  },
                  "Outside the key's IP list": {
                    "value": {
                      "detail": "This API key can't be used from this IP address."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Tidak ada sesi bisnis dengan ID ini dalam aplikasi (tidak pernah dibuat, dihapus, atau dimiliki oleh aplikasi lain). Nilai yang bukan berupa UUID akan mengembalikan halaman HTML `404` alih-alih body JSON ini.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Not found": {
                    "value": {
                      "detail": "Business session not found."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Lebih dari 600 permintaan GET per menit dengan kunci API ini. Tunggu selama jumlah detik di `Retry-After`, lalu coba lagi.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Throttled": {
                    "value": {
                      "detail": "GET request rate limit exceeded. You can make up to 600 requests per minute."
                    }
                  }
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Detik hingga jendela satu menit saat ini direset.",
                "schema": {
                  "type": "integer",
                  "example": 23
                }
              },
              "X-RateLimit-Limit": {
                "description": "Permintaan yang diizinkan per menit dalam anggaran ini.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Permintaan tersisa dalam jendela saat ini.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Waktu Unix saat jendela direset.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/transactions/{transaction_uuid}/pdf/": {
      "get": {
        "summary": "Unduh laporan PDF transaksi",
        "description": "Render satu transaksi yang dipantau sebagai laporan PDF: ringkasan dan putusan, pihak-pihak dan metode pembayaran, properti kustom, alert dan eksekusi aturan, hasil skrining dan Travel Rule, ringkasan jaringan, rincian biaya, hingga 50 transaksi terkait, dan 20 entri aktivitas terbaru. Body adalah PDF itu sendiri (`application/pdf`), bukan JSON.\n\nLaporan dirender dari data transaksi saat ini pada setiap panggilan, jadi mintalah kembali setelah terjadi perubahan status. Tidak ada yang disimpan dan tidak ada yang ditagihkan. Rendering dapat memakan waktu beberapa detik, jadi gunakan batas waktu klien yang cukup longgar.\n\nEndpoint ini berada di jalur berlingkup aplikasi: masukkan ID organisasi Anda dan ID aplikasi tempat kunci API Anda berada di dalam URL ([temukan ID organisasi Anda](https://docs.didit.me/id/getting-started/api-authentication#menemukan-id-organisasi-anda)). Laporan PDF dihitung sebagai media: kunci API dengan cakupan memerlukan `media: read` dan `transactions: read`, serta kunci yang terbatas pada beberapa alur kerja atau sesi yang disetujui tidak dapat memanggilnya.",
        "operationId": "get_transaction_pdf",
        "x-didit-sdk": {
          "resource": "transactions",
          "method": "generate_pdf",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Transactions"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID organisasi.",
            "example": "11111111-2222-3333-4444-555555555555"
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID aplikasi. Harus berupa aplikasi pemilik kunci API tersebut: kunci yang digunakan pada aplikasi lain mana pun akan mendapatkan `403`.",
            "example": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee"
          },
          {
            "name": "transaction_uuid",
            "in": "path",
            "required": true,
            "description": "UUID transaksi Didit: `uuid` yang dikembalikan oleh `POST /v3/transactions/` dan `GET /v3/transactions/`. `txn_id` Anda sendiri tidak diterima.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "abcdef12-3456-7890-abcd-ef1234567890"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl --fail -X GET 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/transactions/abcdef12-3456-7890-abcd-ef1234567890/pdf/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  --output transaction_report.pdf"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\ncontent = client.transactions.generate_pdf(\n    \"abcdef12-3456-7890-abcd-ef1234567890\",\n)\nwith open(\"download.pdf\", \"wb\") as file:\n    file.write(content)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import { writeFile } from \"node:fs/promises\";\nimport Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst content = await didit.transactions.generatePdf(\"abcdef12-3456-7890-abcd-ef1234567890\");\nawait writeFile(\"download.pdf\", Buffer.from(await content.arrayBuffer()));"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresp, err := client.Transactions.GeneratePDF(ctx, \"abcdef12-3456-7890-abcd-ef1234567890\")\nif err != nil {\n\tlog.Fatal(err)\n}\ndefer resp.Body.Close()\nfile, err := os.Create(\"download.pdf\")\nif err != nil {\n\tlog.Fatal(err)\n}\ndefer file.Close()\nif _, err := io.Copy(file, resp.Body); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.nio.file.Path;\nimport me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nclient.transactions().generatePdf(\"abcdef12-3456-7890-abcd-ef1234567890\")\n        .writeTo(Path.of(\"download.pdf\"));"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$content = $didit->transactions->generatePdf('abcdef12-3456-7890-abcd-ef1234567890');\n$content->saveTo('download.pdf');"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\ncontent = didit.transactions.generate_pdf(\"abcdef12-3456-7890-abcd-ef1234567890\")\nFile.binwrite(\"download.pdf\", content)"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar content = await client.Transactions.GeneratePdfAsync(\"abcdef12-3456-7890-abcd-ef1234567890\");\nawait content.SaveToAsync(\"download.pdf\");"
          }
        ],
        "responses": {
          "200": {
            "description": "PDF hasil render, dikembalikan langsung sebagai biner `application/pdf`.",
            "headers": {
              "Content-Disposition": {
                "description": "Selalu `attachment; filename=transaction_{transaction_uuid}.pdf`.",
                "schema": {
                  "type": "string",
                  "example": "attachment; filename=transaction_abcdef12-3456-7890-abcd-ef1234567890.pdf"
                }
              }
            },
            "content": {
              "application/pdf": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "401": {
            "description": "Kunci API telah kedaluwarsa. Hanya kunci yang dibuat dengan tanggal kedaluwarsa yang dapat kedaluwarsa; setelah tanggal tersebut, setiap permintaan dengannya menghasilkan respons `401`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Expired key": {
                    "value": {
                      "detail": "This API key has expired."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Permintaan tidak diizinkan. Baca `detail`: kunci API yang hilang (kunci yang salah, dicabut, atau kedaluwarsa akan menghasilkan `401`), `application_id` yang bukan merupakan aplikasi milik kunci, kunci dengan cakupan terbatas tanpa `media: read` atau `transactions: read`, kunci yang dibatasi untuk alur kerja atau sesi yang disetujui, atau permintaan dari luar daftar IP kunci.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Missing or invalid key": {
                    "value": {
                      "detail": "Authentication credentials were not provided or are invalid."
                    }
                  },
                  "Another application": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Scoped key without media read": {
                    "value": {
                      "detail": "This API key has no read access to media."
                    }
                  },
                  "Scoped key without transactions read": {
                    "value": {
                      "detail": "This API key has no read access to transactions."
                    }
                  },
                  "Key limited to workflows or approved sessions": {
                    "value": {
                      "detail": "This API key only reaches sessions inside its workflow or status limits, so it can't use this endpoint."
                    }
                  },
                  "Outside the key's IP list": {
                    "value": {
                      "detail": "This API key can't be used from this IP address."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Tidak ada transaksi dengan UUID ini di aplikasi tersebut (tidak pernah dibuat, dihapus, atau dimiliki oleh aplikasi lain). `transaction_uuid` yang bukan UUID tidak mencapai API: permintaan ini mengembalikan halaman HTML `404`, bukan body JSON ini.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Not found": {
                    "value": {
                      "detail": "No Transaction matches the given query."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Lebih dari 600 permintaan GET per menit dengan kunci API ini. Tunggu selama jumlah detik di `Retry-After`, lalu coba lagi.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Throttled": {
                    "value": {
                      "detail": "GET request rate limit exceeded. You can make up to 600 requests per minute."
                    }
                  }
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Detik hingga jendela satu menit saat ini direset.",
                "schema": {
                  "type": "integer",
                  "example": 23
                }
              },
              "X-RateLimit-Limit": {
                "description": "Permintaan yang diizinkan per menit dalam anggaran ini.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Permintaan tersisa dalam jendela saat ini.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Waktu Unix saat jendela direset.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/analytics/": {
      "get": {
        "summary": "Dapatkan analitik aplikasi",
        "description": "Baca angka-angka di balik [dasbor analitik](https://docs.didit.me/id/console/analytics) Business Console untuk rentang tanggal tertentu. Tanpa `scope` dan `widget_keys`, responsnya adalah ringkasan verifikasi pengguna (KYC) (`ApplicationAnalyticsSummary`): jumlah sesi harian, total status, tingkat konversi, angka yang sama untuk periode sebelumnya dengan durasi yang sama, lokasi, demografi, perangkat, funnel alur kerja, waktu verifikasi aktif, pengiriman ulang, peringatan, dan deret waktu. Dengan `scope` atau `widget_keys`, responsnya adalah widget dari satu tab dasbor (`ApplicationAnalyticsWidgetResponse`): `kyc`, `kyb`, `transactions`, atau `home`.\n\nJumlah sesi dihitung berdasarkan tanggal pembuatan sesi (UTC) dan mencerminkan status terkini dari setiap sesi. Angka ini berasal dari kompilasi harian yang diperbarui di latar belakang, sehingga aktivitas terbaru mungkin memerlukan waktu sebentar untuk muncul. ID alur kerja dan versi yang tidak valid akan diabaikan alih-alih ditolak. Tidak ada biaya yang dikenakan.\n\nHanya kunci API akses penuh yang dapat memanggil endpoint ini: setiap kunci dengan cakupan terbatas akan menerima `403`, apa pun akses yang dimilikinya, begitu pula kunci milik aplikasi lain. Lihat [Kunci API](https://docs.didit.me/id/console/api-keys).",
        "operationId": "get_application_analytics",
        "x-didit-sdk": {
          "resource": "analytics",
          "method": "retrieve",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Analytics"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID organisasi.",
            "example": "11111111-2222-3333-4444-555555555555"
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID aplikasi. Harus berupa aplikasi pemilik kunci API tersebut: kunci yang digunakan pada aplikasi lain mana pun akan mendapatkan `403`.",
            "example": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee"
          },
          {
            "name": "start_date",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date",
              "example": "2026-10-01"
            },
            "description": "Hari pertama dari rentang, `YYYY-MM-DD`, inklusif (UTC). Kirim bersama dengan `end_date`: jika salah satu tidak ada, keduanya akan diabaikan dan rentang berlangsung dari 30 hari sebelum hari ini hingga hari ini."
          },
          {
            "name": "end_date",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date",
              "example": "2026-10-15"
            },
            "description": "Hari terakhir dari rentang, `YYYY-MM-DD`, inklusif (UTC). Tanggal di masa mendatang dihitung sebagai hari ini. Rentang tidak boleh melebihi 730 hari."
          },
          {
            "name": "scope",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "home",
                "kyc",
                "kyb",
                "transactions"
              ]
            },
            "description": "Tab dasbor tempat widget akan dikembalikan (tidak peka huruf besar/kecil). Hilangkan parameter ini, bersama dengan `widget_keys`, untuk ringkasan KYC. Mengirimkan `widget_keys` saja berarti mengasumsikan `kyc`. `home` menerima widget KYC, KYB, atau transaksi apa pun dan secara default menggunakan tata letak beranda tersimpan milik aplikasi."
          },
          {
            "name": "widget_keys",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "example": "tx_count_total,tx_count_daily"
            },
            "description": "Kunci widget yang dipisahkan dengan koma, dikembalikan dalam urutan ini. Kunci yang tidak didukung oleh cakupan akan diabaikan; jika tidak ada yang tersisa, Anda akan mendapatkan nilai default cakupan. KYC: `kyc_sessions_volume`, `kyc_warning_insights`, `kyc_id_locations`, `kyc_ip_locations`, `kyc_workflow_funnel`, `kyc_average_verification_time`, `kyc_conversion_rate`, `kyc_conversion_by_country`, `kyc_resubmission_insights`, `kyc_original_status_distribution`, `kyc_database_validation_coverage`, `kyc_database_validation_latency`, `kyc_demographics`, `kyc_device_details`. KYB: `kyb_sessions_volume`, `kyb_workflow_funnel`, `kyb_average_verification_time`, `kyb_ip_locations`, `kyb_business_country_distribution`, `kyb_warning_insights`, `kyb_conversion_rate`, `kyb_conversion_by_country`, `kyb_industry_breakdown`, `kyb_resubmission_insights`, `kyb_original_status_distribution`, `kyb_registry_coverage`, `kyb_registry_data_completeness`, `kyb_device_details`. Transaksi: `tx_count_total`, `tx_count_daily`, `tx_volume_total_preferred_currency`, `tx_volume_daily_preferred_currency`, `tx_average_amount`, `tx_average_amount_daily`, `tx_transaction_category_breakdown`, `tx_action_type_breakdown`, `tx_status_volume_trend`, `tx_user_ip_or_country_distribution`, `tx_tag_breakdown`, `tx_top_rules_triggered`, `tx_team_member_performance`, `tx_score_histogram`."
          },
          {
            "name": "workflow_ids",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "example": "33333333-4444-5555-6666-777777777777"
            },
            "description": "ID alur kerja yang dipisahkan koma. Membatasi ringkasan KYC serta widget KYC dan KYB ke alur kerja tersebut. Nilai yang bukan UUID akan diabaikan; jika tidak ada yang valid, filter akan dihapus. Ringkasan ini juga menerima `workflow_id`."
          },
          {
            "name": "versions",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "example": "3,4"
            },
            "description": "Nomor versi alur kerja yang dipisahkan koma. Hanya berlaku bersamaan dengan `workflow_ids`; nilai yang bukan bilangan bulat akan diabaikan. `version` diterima sebagai alias."
          },
          {
            "name": "branch_path_ids",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "example": "default"
            },
            "description": "ID jalur cabang yang dipisahkan koma. Hanya berlaku bersama dengan `workflow_ids`, dan hanya untuk angka KYC. Angka saat ini hanya dicatat untuk `default` (semua jalur digabungkan), sehingga nilai lain apa pun akan mengembalikan angka kosong. `branch_path_id` diterima sebagai alias."
          },
          {
            "name": "tag",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Khusus widget transaksi: UUID tag atau nama tag yang dipisahkan koma."
          },
          {
            "name": "transaction_type",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "example": "finance"
            },
            "description": "Khusus widget transaksi: kategori transaksi yang dipisahkan koma."
          },
          {
            "name": "action_type",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "example": "withdrawal"
            },
            "description": "Khusus widget transaksi: tipe tindakan yang dipisahkan koma (tidak peka huruf besar/kecil)."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/analytics/?start_date=2026-10-01&end_date=2026-10-15' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.analytics.retrieve()\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.analytics.retrieve();\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Analytics.Retrieve(ctx, didit.AnalyticsRetrieveParams{})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.analytics().retrieve();\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->analytics->retrieve();\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.analytics.retrieve\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Analytics.RetrieveAsync();\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "Ringkasan KYC, atau widget yang diminta saat `scope` atau `widget_keys` dikirim.",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/ApplicationAnalyticsSummary"
                    },
                    {
                      "$ref": "#/components/schemas/ApplicationAnalyticsWidgetResponse"
                    }
                  ]
                },
                "examples": {
                  "KYC summary": {
                    "value": {
                      "grouping_mode": "day",
                      "data_points": [
                        {
                          "rounded_date": "2026-10-14",
                          "total": 12,
                          "approved": 8,
                          "declined": 1,
                          "canceled": 1,
                          "pending": 2,
                          "in_review": 1,
                          "expired": 1,
                          "abandoned": 0,
                          "in_progress": 1,
                          "not_started": 0,
                          "manually_approved": 1,
                          "manually_declined": 0
                        },
                        {
                          "rounded_date": "2026-10-15",
                          "total": 10,
                          "approved": 6,
                          "declined": 2,
                          "canceled": 0,
                          "pending": 2,
                          "in_review": 2,
                          "expired": 0,
                          "abandoned": 0,
                          "in_progress": 0,
                          "not_started": 0,
                          "manually_approved": 0,
                          "manually_declined": 1
                        }
                      ],
                      "request_breakdown": {
                        "total_approved": 14,
                        "total_in_review": 3,
                        "total_declined": 3,
                        "total_canceled": 1,
                        "total_pending": 4,
                        "total_expired": 1,
                        "total_abandoned": 0,
                        "total_in_progress": 1,
                        "total_not_started": 0,
                        "total_manually_approved": 1,
                        "total_manually_declined": 1
                      },
                      "conversion_rate": 70.0,
                      "location_stats": {
                        "countries": [
                          {
                            "session_count": 15,
                            "country": "Spain",
                            "country_code": "ES"
                          },
                          {
                            "session_count": 7,
                            "country": "Portugal",
                            "country_code": "PT"
                          }
                        ],
                        "ip_countries": [
                          {
                            "session_count": 15,
                            "country": "Spain",
                            "country_code": "ES"
                          },
                          {
                            "session_count": 7,
                            "country": "Portugal",
                            "country_code": "PT"
                          }
                        ],
                        "id_countries": [
                          {
                            "country": "Spain",
                            "country_code": "ES",
                            "session_count": 14
                          },
                          {
                            "country": "Portugal",
                            "country_code": "PT",
                            "session_count": 6
                          }
                        ],
                        "conversion_by_country": [
                          {
                            "country": "Spain",
                            "country_code": "ES",
                            "finished": 13,
                            "approved": 10
                          },
                          {
                            "country": "Portugal",
                            "country_code": "PT",
                            "finished": 6,
                            "approved": 4
                          }
                        ],
                        "cities": [
                          {
                            "session_count": 9,
                            "location": "Madrid, Spain",
                            "latitude": 40.4168,
                            "longitude": -3.7038
                          }
                        ]
                      },
                      "demographic_stats": {
                        "age_distribution": {
                          "under_18": 0,
                          "18_24": 5,
                          "25_34": 8,
                          "35_44": 4,
                          "45_64": 2,
                          "65_plus": 1
                        },
                        "gender_distribution": {
                          "M": 11,
                          "F": 9
                        }
                      },
                      "device_details": {
                        "device_models": [
                          {
                            "device": "Apple",
                            "count": 12
                          },
                          {
                            "device": "Android",
                            "count": 10
                          }
                        ],
                        "browsers": [
                          {
                            "browser": "Safari",
                            "count": 12
                          },
                          {
                            "browser": "Chrome",
                            "count": 10
                          }
                        ],
                        "operating_systems": [
                          {
                            "os": "iOS",
                            "count": 12
                          },
                          {
                            "os": "Android",
                            "count": 10
                          }
                        ]
                      },
                      "workflow_funnel_stats": {
                        "33333333-4444-5555-6666-777777777777": {
                          "total": 22,
                          "steps": {
                            "OCR": {
                              "reached": 21
                            },
                            "LIVENESS": {
                              "reached": 19
                            },
                            "FACE_MATCH": {
                              "reached": 19
                            },
                            "AML": {
                              "reached": 18
                            }
                          }
                        }
                      },
                      "verification_time_stats": {
                        "overall_avg_seconds": 64.0,
                        "overall_count": 18,
                        "per_feature": {
                          "OCR": {
                            "avg_seconds": 41.2,
                            "total_seconds": 741.6,
                            "count": 18
                          },
                          "LIVENESS": {
                            "avg_seconds": 22.8,
                            "total_seconds": 410.4,
                            "count": 18
                          }
                        },
                        "per_sub_step": {
                          "OCR": {
                            "front_id_photo": {
                              "avg_seconds": 18.3,
                              "total_seconds": 329.4,
                              "count": 18
                            }
                          }
                        }
                      },
                      "resubmission_stats": {
                        "first_pass": 17,
                        "second": 2,
                        "third_plus": 1,
                        "abandoned": 0
                      },
                      "warning_stats": {
                        "ID_VERIFICATION": {
                          "total": 21,
                          "risks": {
                            "DOCUMENT_EXPIRED": {
                              "error": 1,
                              "warning": 0,
                              "information": 0
                            }
                          }
                        },
                        "LIVENESS": {
                          "total": 19,
                          "risks": {
                            "LOW_LIVENESS_SCORE": {
                              "error": 0,
                              "warning": 2,
                              "information": 0
                            }
                          }
                        }
                      },
                      "original_status_stats": {
                        "approved": 13,
                        "in_review": 5,
                        "declined": 2
                      },
                      "demographic_time_series": [
                        {
                          "date": "2026-10-14",
                          "age_distribution": {
                            "under_18": 0,
                            "18_24": 3,
                            "25_34": 4,
                            "35_44": 2,
                            "45_64": 1,
                            "65_plus": 0
                          },
                          "gender_distribution": {
                            "M": 6,
                            "F": 4
                          }
                        },
                        {
                          "date": "2026-10-15",
                          "age_distribution": {
                            "under_18": 0,
                            "18_24": 2,
                            "25_34": 4,
                            "35_44": 2,
                            "45_64": 1,
                            "65_plus": 1
                          },
                          "gender_distribution": {
                            "M": 5,
                            "F": 5
                          }
                        }
                      ],
                      "device_time_series": [
                        {
                          "date": "2026-10-14",
                          "devices": {
                            "Apple": 7,
                            "Android": 5
                          },
                          "browsers": {
                            "Safari": 7,
                            "Chrome": 5
                          },
                          "operating_systems": {
                            "iOS": 7,
                            "Android": 5
                          }
                        },
                        {
                          "date": "2026-10-15",
                          "devices": {
                            "Apple": 5,
                            "Android": 5
                          },
                          "browsers": {
                            "Safari": 5,
                            "Chrome": 5
                          },
                          "operating_systems": {
                            "iOS": 5,
                            "Android": 5
                          }
                        }
                      ],
                      "verification_time_time_series": [
                        {
                          "date": "2026-10-14",
                          "overall_avg": 66.1,
                          "per_feature": {
                            "OCR": 42.0,
                            "LIVENESS": 24.1
                          }
                        },
                        {
                          "date": "2026-10-15",
                          "overall_avg": 61.5,
                          "per_feature": {
                            "OCR": 40.2,
                            "LIVENESS": 21.3
                          }
                        }
                      ],
                      "resubmission_time_series": [
                        {
                          "date": "2026-10-14",
                          "first_pass": 9,
                          "second": 1,
                          "third_plus": 0,
                          "abandoned": 0
                        },
                        {
                          "date": "2026-10-15",
                          "first_pass": 8,
                          "second": 1,
                          "third_plus": 1,
                          "abandoned": 0
                        }
                      ],
                      "original_status_time_series": [
                        {
                          "date": "2026-10-14",
                          "approved": 7,
                          "in_review": 3,
                          "declined": 1
                        },
                        {
                          "date": "2026-10-15",
                          "approved": 6,
                          "in_review": 2,
                          "declined": 1
                        }
                      ],
                      "previous_data_points": [
                        {
                          "rounded_date": "2026-10-12",
                          "total": 9,
                          "approved": 6,
                          "declined": 1,
                          "canceled": 1,
                          "pending": 1
                        },
                        {
                          "rounded_date": "2026-10-13",
                          "total": 11,
                          "approved": 7,
                          "declined": 2,
                          "canceled": 0,
                          "pending": 2
                        }
                      ],
                      "previous_request_breakdown": {
                        "total_approved": 13,
                        "total_in_review": 2,
                        "total_declined": 3,
                        "total_canceled": 1,
                        "total_pending": 3
                      }
                    }
                  },
                  "Transaction widgets": {
                    "value": {
                      "scope": "transactions",
                      "available_widget_keys": [
                        "tx_count_total",
                        "tx_count_daily",
                        "tx_volume_total_preferred_currency",
                        "tx_volume_daily_preferred_currency",
                        "tx_average_amount",
                        "tx_average_amount_daily",
                        "tx_transaction_category_breakdown",
                        "tx_action_type_breakdown",
                        "tx_status_volume_trend",
                        "tx_user_ip_or_country_distribution",
                        "tx_tag_breakdown",
                        "tx_top_rules_triggered",
                        "tx_team_member_performance",
                        "tx_score_histogram"
                      ],
                      "requested_widget_keys": [
                        "tx_count_total",
                        "tx_count_daily"
                      ],
                      "widgets": {
                        "tx_count_total": {
                          "kind": "metric",
                          "title": "Transaction count",
                          "value": 42
                        },
                        "tx_count_daily": {
                          "kind": "time_series",
                          "title": "Transaction count",
                          "items": [
                            {
                              "date": "2026-10-14",
                              "value": 20
                            },
                            {
                              "date": "2026-10-15",
                              "value": 22
                            }
                          ],
                          "previous_items": [
                            {
                              "date": "2026-10-12",
                              "value": 18
                            },
                            {
                              "date": "2026-10-13",
                              "value": 15
                            }
                          ]
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Rentang tanggal atau cakupan tidak valid. Body berupa objek yang diberi kunci berdasarkan parameter yang bermasalah, dengan pesan string.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": {
                    "type": "string"
                  }
                },
                "examples": {
                  "Bad date format": {
                    "value": {
                      "start_date": "Invalid date format. Use YYYY-MM-DD (e.g., 2024-01-15)."
                    }
                  },
                  "Start after end": {
                    "value": {
                      "start_date": "Start date must be before or equal to end date."
                    }
                  },
                  "Range too long": {
                    "value": {
                      "date_range": "Date range cannot exceed 730 days (2 years)."
                    }
                  },
                  "Unknown scope": {
                    "value": {
                      "scope": "Unsupported analytics scope."
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Kunci API telah kedaluwarsa. Hanya kunci yang dibuat dengan tanggal kedaluwarsa yang dapat kedaluwarsa; setelah tanggal tersebut, setiap permintaan dengannya menghasilkan respons `401`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Expired key": {
                    "value": {
                      "detail": "This API key has expired."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Permintaan tidak diizinkan. Baca `detail`: kunci API yang hilang (kunci yang salah, dicabut, atau kedaluwarsa akan menghasilkan `401`), kunci dari aplikasi lain, kunci dengan cakupan terbatas apa pun, atau permintaan dari luar daftar IP kunci.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Missing or invalid key": {
                    "value": {
                      "detail": "Authentication credentials were not provided or are invalid."
                    }
                  },
                  "Another application": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Scoped key": {
                    "value": {
                      "detail": "This API key has no access to this endpoint."
                    }
                  },
                  "Outside the key's IP list": {
                    "value": {
                      "detail": "This API key can't be used from this IP address."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Lebih dari 600 permintaan GET per menit dengan kunci API ini. Tunggu selama jumlah detik di `Retry-After`, lalu coba lagi.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Throttled": {
                    "value": {
                      "detail": "GET request rate limit exceeded. You can make up to 600 requests per minute."
                    }
                  }
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Detik hingga jendela satu menit saat ini direset.",
                "schema": {
                  "type": "integer",
                  "example": 23
                }
              },
              "X-RateLimit-Limit": {
                "description": "Permintaan yang diizinkan per menit dalam anggaran ini.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Permintaan tersisa dalam jendela saat ini.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Waktu Unix saat jendela direset.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/analytics/today/": {
      "get": {
        "summary": "Dapatkan verifikasi hari ini berdasarkan jam",
        "operationId": "get_application_analytics_today",
        "x-didit-sdk": {
          "resource": "analytics",
          "method": "retrieve_today",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Analytics"
        ],
        "description": "Sesi verifikasi pengguna (KYC) hari ini, dari tengah malam lokal di `tz`, dihitung per jam lokal saat dibuat, disandingkan dengan jam yang sama pada hari yang sama seminggu sebelumnya, dan dibagi berdasarkan hasil yang dimiliki masing-masing sesi saat ini: disetujui, dalam peninjauan, atau ditolak. Ini adalah kartu volume di Beranda Business Console.\n\n`total` adalah hari ini sejauh ini. `previous_total_so_far` menghitung hari pembanding hanya sampai waktu lokal yang sama, sehingga perubahan di antara keduanya membandingkan bagian yang sama dari kedua hari tersebut. Jam-jam yang belum tiba hari ini bernilai `0`. Hari saat pergantian jam (daylight saving) memiliki 23 atau 25 jam: jam yang hilang tetap `0` dan jam yang berulang menampung keduanya.",
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID organisasi.",
            "example": "11111111-2222-3333-4444-555555555555"
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID aplikasi. Harus berupa aplikasi pemilik kunci API tersebut: kunci yang digunakan pada aplikasi lain mana pun akan mendapatkan `403`.",
            "example": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee"
          },
          {
            "name": "tz",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "default": "UTC",
              "example": "Europe/Madrid"
            },
            "description": "Zona waktu IANA yang tengah malamnya memulai hari ini, misalnya `Europe/Madrid` atau `America/Mexico_City`. Jangan sertakan untuk UTC."
          }
        ],
        "responses": {
          "200": {
            "description": "Verifikasi hari ini berdasarkan jam lokal, verifikasi pada hari pembanding, dan hasil hari ini.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApplicationAnalyticsToday"
                },
                "examples": {
                  "Madrid, 14:00": {
                    "value": {
                      "time_zone": "Europe/Madrid",
                      "date": "2026-10-30",
                      "current_hour": 14,
                      "previous_date": "2026-10-23",
                      "hours": [
                        3,
                        1,
                        0,
                        0,
                        1,
                        2,
                        4,
                        9,
                        14,
                        18,
                        21,
                        19,
                        22,
                        24,
                        27,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0,
                        0
                      ],
                      "previous_hours": [
                        2,
                        1,
                        1,
                        0,
                        1,
                        3,
                        5,
                        8,
                        12,
                        16,
                        19,
                        18,
                        20,
                        22,
                        24,
                        26,
                        23,
                        19,
                        15,
                        12,
                        9,
                        7,
                        5,
                        3
                      ],
                      "total": 165,
                      "previous_total_so_far": 151,
                      "outcomes": {
                        "approved": 139,
                        "in_review": 6,
                        "declined": 18
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Zona waktu tidak dikenal. Bagian body menggunakan parameter sebagai kunci, dengan daftar pesan.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Unknown time zone": {
                    "value": {
                      "tz": [
                        "Unknown time zone: Europe/Atlantis."
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Kunci API telah kedaluwarsa. Hanya kunci yang dibuat dengan tanggal kedaluwarsa yang dapat kedaluwarsa; setelah tanggal tersebut, setiap permintaan dengannya menghasilkan respons `401`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Expired key": {
                    "value": {
                      "detail": "This API key has expired."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Permintaan tidak diizinkan. Baca `detail`: kunci API yang hilang atau tidak valid (tidak pernah `401`), kunci dari aplikasi lain, kunci dengan cakupan terbatas apa pun, atau permintaan dari luar daftar IP kunci.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Missing or invalid key": {
                    "value": {
                      "detail": "Authentication credentials were not provided or are invalid."
                    }
                  },
                  "Another application": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Scoped key": {
                    "value": {
                      "detail": "This API key has no access to this endpoint."
                    }
                  },
                  "Outside the key's IP list": {
                    "value": {
                      "detail": "This API key can't be used from this IP address."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Lebih dari 600 permintaan GET per menit dengan kunci API ini. Tunggu selama jumlah detik di `Retry-After`, lalu coba lagi.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Throttled": {
                    "value": {
                      "detail": "GET request rate limit exceeded. You can make up to 600 requests per minute."
                    }
                  }
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Detik hingga jendela satu menit saat ini direset.",
                "schema": {
                  "type": "integer",
                  "example": 23
                }
              },
              "X-RateLimit-Limit": {
                "description": "Permintaan yang diizinkan per menit dalam anggaran ini.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Permintaan tersisa dalam jendela saat ini.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "description": "Waktu Unix saat jendela direset.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/analytics/today/?tz=Europe%2FMadrid' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          }
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/session/{sessionId}/webhooks/": {
      "get": {
        "summary": "Mencantumkan daftar pengiriman webhook sesi",
        "description": "Daftar setiap pengiriman webhook yang dicatat Didit untuk satu sesi verifikasi, pengguna (KYC) atau bisnis (KYB), terbaru lebih dahulu, sebagai array JSON biasa (tanpa paginasi). Setiap entri mewakili satu upaya ke satu tujuan: pengiriman pertama, setiap [percobaan ulang](https://docs.didit.me/id/integration/webhooks#kebijakan-coba-lagi) otomatis, dan setiap pengiriman ulang merupakan entri terpisah dengan `uuid` masing-masing, serta percobaan ulang dan pengiriman ulang tetap mempertahankan `event_id` payload. `request_header` dan `request_body` adalah teks JSON; uraikan keduanya untuk membaca tanda tangan dan payload. Catatan pengiriman tersedia selama sekitar 30 hari, sehingga array kosong berarti belum ada webhook yang dikirim untuk sesi tersebut atau semua pengiriman lebih lama dari rentang waktu itu. Kunci API dengan cakupan khusus memerlukan `sessions: read` dan `decisions: read`.",
        "operationId": "get_v3_session_webhooks",
        "x-didit-sdk": {
          "resource": "sessions.webhooks",
          "method": "list",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Sessions"
        ],
        "parameters": [
          {
            "name": "sessionId",
            "in": "path",
            "required": true,
            "description": "UUID sesi verifikasi, pengguna (KYC) atau bisnis (KYB): `session_id` yang dikembalikan oleh `POST /v3/session/`. Server mencari ID tersebut di kedua jenis sesi.\n\n**Harus berupa UUID yang valid.** Rute ini hanya cocok dengan UUID yang terbentuk dengan benar, sehingga nilai yang salah format akan ditolak oleh router URL sebelum kode aplikasi apa pun berjalan dan responsnya berupa halaman **HTML** `404`, bukan envelope JSON `{\"detail\": ...}` yang ditunjukkan di bawah.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "22222222-3333-4444-5555-666666666666"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/session/22222222-3333-4444-5555-666666666666/webhooks/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.webhooks.list(\n    \"22222222-3333-4444-5555-666666666666\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.webhooks.list(\"22222222-3333-4444-5555-666666666666\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.Webhooks.List(ctx, \"22222222-3333-4444-5555-666666666666\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().webhooks().list(\"22222222-3333-4444-5555-666666666666\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->sessions->webhooks->list('22222222-3333-4444-5555-666666666666');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.sessions.webhooks.list(\"22222222-3333-4444-5555-666666666666\").each do |item|\n  puts item.to_h\nend"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.Webhooks.ListAsync(\"22222222-3333-4444-5555-666666666666\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "Setiap pengiriman yang tercatat untuk sesi ini, yang terbaru terlebih dahulu.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/SessionWebhookDelivery"
                  }
                },
                "examples": {
                  "Failed delivery and its successful retry": {
                    "value": [
                      {
                        "uuid": "66666666-7777-8888-9999-000000000002",
                        "session_id": "22222222-3333-4444-5555-666666666666",
                        "request_url": "https://yourapp.com/webhooks/didit",
                        "response_status": 200,
                        "status": "In Progress",
                        "webhook_type": "status.updated",
                        "request_header": "{\"Content-Type\": \"application/json\", \"X-Signature\": \"9188851d160b5b3aacfc946e4dde1f061b7e568662518942c927ddaf507f533d\", \"X-Signature-V2\": \"381236af514d3fb538579365ac5a24f2464ce1b8224c6e770c60d8201c43ecc5\", \"X-Signature-Simple\": \"4740131dc38f29e78a8508371979be74967d5307464494bd3148a03b4d6c8716\", \"X-Timestamp\": \"1792056139\", \"User-Agent\": \"DiditWebhook/2.0 +https://didit.me\"}",
                        "request_body": "{\"application_id\":\"aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee\",\"created_at\":1792056057,\"environment\":\"live\",\"event_id\":\"33333333-4444-5555-6666-777777777777\",\"sandbox_scenario\":null,\"session_id\":\"22222222-3333-4444-5555-666666666666\",\"status\":\"In Progress\",\"timestamp\":1792056139,\"vendor_data\":\"user-123\",\"webhook_type\":\"status.updated\",\"workflow_id\":\"44444444-5555-6666-7777-888888888888\",\"workflow_version\":3}",
                        "created_at": "2026-10-15T09:22:19.104233Z"
                      },
                      {
                        "uuid": "66666666-7777-8888-9999-000000000001",
                        "session_id": "22222222-3333-4444-5555-666666666666",
                        "request_url": "https://yourapp.com/webhooks/didit",
                        "response_status": 503,
                        "status": "In Progress",
                        "webhook_type": "status.updated",
                        "request_header": "{\"Content-Type\": \"application/json\", \"X-Signature\": \"a5e02a03404e1337a0198e6be15d34abbd053c658a0e51e5d0e78554213ef29b\", \"X-Signature-V2\": \"927e7cb770c94ce745939bff73f04aa200015f3bc64795ba46c2aaf78a6cedc5\", \"X-Signature-Simple\": \"e37b0d4c716c72bb5ae7127b9cc455d28ab4686e9e22312b4ec2327409a73302\", \"X-Timestamp\": \"1792056078\", \"User-Agent\": \"DiditWebhook/2.0 +https://didit.me\"}",
                        "request_body": "{\"application_id\":\"aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee\",\"created_at\":1792056057,\"environment\":\"live\",\"event_id\":\"33333333-4444-5555-6666-777777777777\",\"sandbox_scenario\":null,\"session_id\":\"22222222-3333-4444-5555-666666666666\",\"status\":\"In Progress\",\"timestamp\":1792056078,\"vendor_data\":\"user-123\",\"webhook_type\":\"status.updated\",\"workflow_id\":\"44444444-5555-6666-7777-888888888888\",\"workflow_version\":3}",
                        "created_at": "2026-10-15T09:21:18.412345Z"
                      }
                    ]
                  },
                  "No webhook sent yet": {
                    "value": []
                  }
                }
              }
            }
          },
          "401": {
            "description": "Kunci API telah kedaluwarsa: kunci ini dibuat dengan tanggal kedaluwarsa yang telah lewat. Kunci yang salah atau dicabut juga menghasilkan `401`; kunci yang tidak ada menghasilkan `403`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "Pesan kesalahan yang mudah dibaca manusia."
                    }
                  }
                },
                "examples": {
                  "Expired key": {
                    "value": {
                      "detail": "This API key has expired."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Permintaan tidak diizinkan. Tidak adanya `x-api-key`, atau kunci yang tidak valid atau dicabut, akan menghasilkan `Authentication credentials were not provided or are invalid.` Kunci dari aplikasi lain akan menghasilkan `You do not have permission to perform this action.` Kunci dengan cakupan terbatas tanpa akses yang dibutuhkan endpoint ini akan menghasilkan pesan yang menyebutkan akses yang hilang, dan kunci yang digunakan dari luar daftar izin IP-nya akan menghasilkan `This API key can't be used from this IP address.` `sessionId` yang tidak dikenal akan mengembalikan `404` sebelum kredensial diperiksa.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "Pesan kesalahan yang mudah dibaca manusia."
                    }
                  }
                },
                "examples": {
                  "Missing or invalid key": {
                    "value": {
                      "detail": "Authentication credentials were not provided or are invalid."
                    }
                  },
                  "Key of another application": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Scoped key without sessions read": {
                    "value": {
                      "detail": "This API key has no read access to sessions."
                    }
                  },
                  "Scoped key without decisions read": {
                    "value": {
                      "detail": "This API key has no read access to decisions."
                    }
                  },
                  "Outside the IP allowlist": {
                    "value": {
                      "detail": "This API key can't be used from this IP address."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Sesi tidak ada atau telah dihapus (`Not found.`, dikembalikan sebelum kredensial diperiksa), atau berada di luar batas alur kerja atau status dari kunci dengan cakupan terbatas (`Session not found.`).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "Pesan kesalahan yang mudah dibaca manusia."
                    }
                  }
                },
                "examples": {
                  "Unknown session": {
                    "value": {
                      "detail": "Not found."
                    }
                  },
                  "Outside the key's limits": {
                    "value": {
                      "detail": "Session not found."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Batas laju terlampaui: lebih dari 600 permintaan GET dalam jendela satu menit saat ini untuk kunci API ini. Tunggu `Retry-After` detik sebelum mencoba lagi.",
            "headers": {
              "Retry-After": {
                "description": "Detik untuk menunggu sebelum mencoba lagi.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "example": 30
                }
              },
              "X-RateLimit-Limit": {
                "description": "Permintaan yang diizinkan dalam jendela satu menit (600).",
                "schema": {
                  "type": "integer",
                  "example": 600
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Permintaan tersisa dalam jendela saat ini.",
                "schema": {
                  "type": "integer",
                  "example": 0
                }
              },
              "X-RateLimit-Reset": {
                "description": "Waktu Unix (detik) saat jendela saat ini direset.",
                "schema": {
                  "type": "integer",
                  "example": 1792056120
                }
              },
              "X-RateLimit-Scope": {
                "description": "Nama anggaran yang terlampaui.",
                "schema": {
                  "type": "string",
                  "example": "generic-get"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "Pesan kesalahan yang mudah dibaca manusia."
                    }
                  }
                },
                "examples": {
                  "Throttled": {
                    "value": {
                      "detail": "GET request rate limit exceeded. You can make up to 600 requests per minute."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/session/{sessionId}/webhook/{webhook_uuid}": {
      "get": {
        "summary": "Dapatkan pengiriman webhook sesi",
        "description": "Ambil satu pengiriman webhook dari sesi verifikasi: URL tujuannya, status HTTP yang dikembalikan endpoint Anda, serta header dan isi JSON persis yang dikirimkan Didit. `request_header` dan `request_body` berupa teks JSON; untuk memeriksa [verifikasi tanda tangan](https://docs.didit.me/id/integration/webhooks#verifikasi-tanda-tangan) Anda, hitung ulang `X-Signature-V2` dari isi yang telah di-parsing menggunakan rahasia milik tujuan pengiriman (atau rahasia tingkat aplikasi untuk pengiriman ke URL webhook lama). Jalur tidak memiliki garis miring di akhir: jika ada, endpoint mengembalikan `404`. Kunci API dengan pembatasan cakupan memerlukan `sessions: read` dan `decisions: read`.",
        "operationId": "get_v3_session_webhook",
        "x-didit-sdk": {
          "resource": "sessions.webhooks",
          "method": "retrieve",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Sessions"
        ],
        "parameters": [
          {
            "name": "sessionId",
            "in": "path",
            "required": true,
            "description": "UUID sesi verifikasi, pengguna (KYC) atau bisnis (KYB): `session_id` yang dikembalikan oleh `POST /v3/session/`. Server mencari ID tersebut di kedua jenis sesi.\n\n**Harus berupa UUID yang valid.** Rute ini hanya cocok dengan UUID yang terbentuk dengan benar, sehingga nilai yang salah format akan ditolak oleh router URL sebelum kode aplikasi apa pun berjalan dan responsnya berupa halaman **HTML** `404`, bukan envelope JSON `{\"detail\": ...}` yang ditunjukkan di bawah.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "22222222-3333-4444-5555-666666666666"
          },
          {
            "name": "webhook_uuid",
            "in": "path",
            "required": true,
            "description": "UUID pengiriman: `uuid` dari entri yang dikembalikan oleh `GET /v3/session/{sessionId}/webhooks/`. Pengiriman ini harus dimiliki oleh sesi di path tersebut.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "66666666-7777-8888-9999-000000000001"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/session/22222222-3333-4444-5555-666666666666/webhook/66666666-7777-8888-9999-000000000001' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.webhooks.retrieve(\n    \"22222222-3333-4444-5555-666666666666\",\n    \"66666666-7777-8888-9999-000000000001\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.webhooks.retrieve(\n  \"22222222-3333-4444-5555-666666666666\",\n  \"66666666-7777-8888-9999-000000000001\",\n);\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.Webhooks.Retrieve(ctx, \"22222222-3333-4444-5555-666666666666\", \"66666666-7777-8888-9999-000000000001\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().webhooks().retrieve(\"22222222-3333-4444-5555-666666666666\", \"66666666-7777-8888-9999-000000000001\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->sessions->webhooks->retrieve('22222222-3333-4444-5555-666666666666', '66666666-7777-8888-9999-000000000001');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.webhooks.retrieve(\n  \"22222222-3333-4444-5555-666666666666\",\n  \"66666666-7777-8888-9999-000000000001\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.Webhooks.RetrieveAsync(\"22222222-3333-4444-5555-666666666666\", \"66666666-7777-8888-9999-000000000001\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "Pengiriman, beserta header dan body permintaannya.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SessionWebhookDelivery"
                },
                "examples": {
                  "Connection failure": {
                    "value": {
                      "uuid": "66666666-7777-8888-9999-000000000001",
                      "session_id": "22222222-3333-4444-5555-666666666666",
                      "request_url": "https://yourapp.com/webhooks/didit",
                      "response_status": 503,
                      "status": "In Progress",
                      "webhook_type": "status.updated",
                      "request_header": "{\"Content-Type\": \"application/json\", \"X-Signature\": \"a5e02a03404e1337a0198e6be15d34abbd053c658a0e51e5d0e78554213ef29b\", \"X-Signature-V2\": \"927e7cb770c94ce745939bff73f04aa200015f3bc64795ba46c2aaf78a6cedc5\", \"X-Signature-Simple\": \"e37b0d4c716c72bb5ae7127b9cc455d28ab4686e9e22312b4ec2327409a73302\", \"X-Timestamp\": \"1792056078\", \"User-Agent\": \"DiditWebhook/2.0 +https://didit.me\"}",
                      "request_body": "{\"application_id\":\"aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee\",\"created_at\":1792056057,\"environment\":\"live\",\"event_id\":\"33333333-4444-5555-6666-777777777777\",\"sandbox_scenario\":null,\"session_id\":\"22222222-3333-4444-5555-666666666666\",\"status\":\"In Progress\",\"timestamp\":1792056078,\"vendor_data\":\"user-123\",\"webhook_type\":\"status.updated\",\"workflow_id\":\"44444444-5555-6666-7777-888888888888\",\"workflow_version\":3}",
                      "created_at": "2026-10-15T09:21:18.412345Z"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Kunci API telah kedaluwarsa: kunci ini dibuat dengan tanggal kedaluwarsa yang telah lewat. Kunci yang salah atau dicabut juga menghasilkan `401`; kunci yang tidak ada menghasilkan `403`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "Pesan kesalahan yang mudah dibaca manusia."
                    }
                  }
                },
                "examples": {
                  "Expired key": {
                    "value": {
                      "detail": "This API key has expired."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Permintaan tidak diizinkan. Tidak adanya `x-api-key`, atau kunci yang tidak valid atau dicabut, akan menghasilkan `Authentication credentials were not provided or are invalid.` Kunci dari aplikasi lain akan menghasilkan `You do not have permission to perform this action.` Kunci dengan cakupan terbatas tanpa akses yang dibutuhkan endpoint ini akan menghasilkan pesan yang menyebutkan akses yang hilang, dan kunci yang digunakan dari luar daftar izin IP-nya akan menghasilkan `This API key can't be used from this IP address.` `sessionId` yang tidak dikenal akan mengembalikan `404` sebelum kredensial diperiksa.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "Pesan kesalahan yang mudah dibaca manusia."
                    }
                  }
                },
                "examples": {
                  "Missing or invalid key": {
                    "value": {
                      "detail": "Authentication credentials were not provided or are invalid."
                    }
                  },
                  "Key of another application": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Scoped key without sessions read": {
                    "value": {
                      "detail": "This API key has no read access to sessions."
                    }
                  },
                  "Scoped key without decisions read": {
                    "value": {
                      "detail": "This API key has no read access to decisions."
                    }
                  },
                  "Outside the IP allowlist": {
                    "value": {
                      "detail": "This API key can't be used from this IP address."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Sesi tidak ada atau telah dihapus (`Not found.`, dikembalikan sebelum kredensial diperiksa), atau berada di luar batas alur kerja atau status dari kunci dengan cakupan terbatas (`Session not found.`). Pengiriman yang tidak ada, milik sesi lain, atau tidak lagi tersedia mengembalikan `No WebhookLog matches the given query.`",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "Pesan kesalahan yang mudah dibaca manusia."
                    }
                  }
                },
                "examples": {
                  "Unknown session": {
                    "value": {
                      "detail": "Not found."
                    }
                  },
                  "Outside the key's limits": {
                    "value": {
                      "detail": "Session not found."
                    }
                  },
                  "Delivery not in this session": {
                    "value": {
                      "detail": "No WebhookLog matches the given query."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Batas laju terlampaui: lebih dari 600 permintaan GET dalam jendela satu menit saat ini untuk kunci API ini. Tunggu `Retry-After` detik sebelum mencoba lagi.",
            "headers": {
              "Retry-After": {
                "description": "Detik untuk menunggu sebelum mencoba lagi.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "example": 30
                }
              },
              "X-RateLimit-Limit": {
                "description": "Permintaan yang diizinkan dalam jendela satu menit (600).",
                "schema": {
                  "type": "integer",
                  "example": 600
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Permintaan tersisa dalam jendela saat ini.",
                "schema": {
                  "type": "integer",
                  "example": 0
                }
              },
              "X-RateLimit-Reset": {
                "description": "Waktu Unix (detik) saat jendela saat ini direset.",
                "schema": {
                  "type": "integer",
                  "example": 1792056120
                }
              },
              "X-RateLimit-Scope": {
                "description": "Nama anggaran yang terlampaui.",
                "schema": {
                  "type": "string",
                  "example": "generic-get"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "Pesan kesalahan yang mudah dibaca manusia."
                    }
                  }
                },
                "examples": {
                  "Throttled": {
                    "value": {
                      "detail": "GET request rate limit exceeded. You can make up to 600 requests per minute."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/session/{sessionId}/webhook/{webhook_uuid}/resend": {
      "post": {
        "summary": "Kirim ulang pengiriman webhook sesi",
        "description": "Kirim kembali webhook sesi yang tercatat ke URL tujuannya semula, dengan payload dan `event_id` yang sama serta `timestamp`, header `X-Timestamp`, dan tanda tangan baru. Didit menandatanganinya dengan rahasia saat ini dari tujuan pengiriman tersebut (atau rahasia tingkat aplikasi untuk pengiriman ke URL webhook lama), menunggu hingga 5 detik untuk endpoint Anda, mencatat upaya tersebut sebagai pengiriman baru, dan mengembalikannya dengan `200` apa pun jawaban endpoint Anda: baca `response_status`. Pengiriman ulang tidak dicoba lagi secara otomatis, dan setiap panggilan mengirim kembali, jadi buat endpoint Anda idempoten pada `event_id`. Jalur tidak memiliki garis miring di akhir dan permintaan tidak memiliki body. Kunci API dengan pembatasan cakupan memerlukan `webhooks: write` dan `decisions: read`.",
        "operationId": "post_v3_session_webhook_resend",
        "x-didit-sdk": {
          "resource": "sessions.webhooks",
          "method": "resend",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Sessions"
        ],
        "parameters": [
          {
            "name": "sessionId",
            "in": "path",
            "required": true,
            "description": "UUID sesi verifikasi, pengguna (KYC) atau bisnis (KYB): `session_id` yang dikembalikan oleh `POST /v3/session/`. Server mencari ID tersebut di kedua jenis sesi.\n\n**Harus berupa UUID yang valid.** Rute ini hanya cocok dengan UUID yang terbentuk dengan benar, sehingga nilai yang salah format akan ditolak oleh router URL sebelum kode aplikasi apa pun berjalan dan responsnya berupa halaman **HTML** `404`, bukan envelope JSON `{\"detail\": ...}` yang ditunjukkan di bawah.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "22222222-3333-4444-5555-666666666666"
          },
          {
            "name": "webhook_uuid",
            "in": "path",
            "required": true,
            "description": "UUID pengiriman yang akan dikirim ulang: `uuid` dari entri yang dikembalikan oleh `GET /v3/session/{sessionId}/webhooks/`. Pengiriman ini harus dimiliki oleh sesi di path tersebut.",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "example": "66666666-7777-8888-9999-000000000001"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://verification.didit.me/v3/session/22222222-3333-4444-5555-666666666666/webhook/66666666-7777-8888-9999-000000000001/resend' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.webhooks.resend(\n    \"22222222-3333-4444-5555-666666666666\",\n    \"66666666-7777-8888-9999-000000000001\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.webhooks.resend(\n  \"22222222-3333-4444-5555-666666666666\",\n  \"66666666-7777-8888-9999-000000000001\",\n);\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.Webhooks.Resend(ctx, \"22222222-3333-4444-5555-666666666666\", \"66666666-7777-8888-9999-000000000001\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().webhooks().resend(\"22222222-3333-4444-5555-666666666666\", \"66666666-7777-8888-9999-000000000001\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->sessions->webhooks->resend('22222222-3333-4444-5555-666666666666', '66666666-7777-8888-9999-000000000001');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.webhooks.resend(\n  \"22222222-3333-4444-5555-666666666666\",\n  \"66666666-7777-8888-9999-000000000001\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.Webhooks.ResendAsync(\"22222222-3333-4444-5555-666666666666\", \"66666666-7777-8888-9999-000000000001\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "Pengiriman baru, yang sudah dicoba. `response_status` adalah respons yang diberikan endpoint Anda kali ini. Pengiriman asli tidak berubah.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SessionWebhookDelivery"
                },
                "examples": {
                  "Accepted on resend": {
                    "value": {
                      "uuid": "66666666-7777-8888-9999-000000000004",
                      "session_id": "22222222-3333-4444-5555-666666666666",
                      "request_url": "https://yourapp.com/webhooks/didit",
                      "response_status": 200,
                      "status": "In Progress",
                      "webhook_type": "status.updated",
                      "request_header": "{\"Content-Type\": \"application/json\", \"X-Signature\": \"b8eb1e376517ee0cad8ba98ff7f8fd35fc72eca231000963a96a335f82328835\", \"X-Signature-V2\": \"9efd2ce9ed1303e1d05273ef9608a59363ed9789a05253db4748b3e8e50cb109\", \"X-Signature-Simple\": \"bf3a9dc04b2c20ab539203b0cd5cca2a10f630bf62d8feb6d68d82af80f64774\", \"X-Timestamp\": \"1792159542\", \"User-Agent\": \"DiditWebhook/2.0 +https://didit.me\"}",
                      "request_body": "{\"application_id\":\"aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee\",\"created_at\":1792056057,\"environment\":\"live\",\"event_id\":\"33333333-4444-5555-6666-777777777777\",\"sandbox_scenario\":null,\"session_id\":\"22222222-3333-4444-5555-666666666666\",\"status\":\"In Progress\",\"timestamp\":1792159542,\"vendor_data\":\"user-123\",\"webhook_type\":\"status.updated\",\"workflow_id\":\"44444444-5555-6666-7777-888888888888\",\"workflow_version\":3}",
                      "created_at": "2026-10-16T14:05:42.330981Z"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Pengiriman tidak dapat dikirim ulang. Percabangan berdasarkan `code`: `webhook_url_missing` berarti pengiriman tidak memiliki URL yang tercatat dan tidak ada yang dikirim; `webhook_resend_error` berarti pengiriman yang disimpan tidak dapat ditandatangani ulang atau upaya tersebut tidak dapat diselesaikan. Setelah `webhook_resend_error`, `detail` dimulai dengan `Error processing webhook resend:` diikuti oleh teks diagnostik yang dapat berubah.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "Pesan kesalahan yang mudah dibaca manusia."
                    },
                    "code": {
                      "type": "string",
                      "description": "Kode error stabil yang dapat dibaca mesin. Buat percabangan logika berdasarkan ini, bukan pada `detail`."
                    }
                  }
                },
                "examples": {
                  "No recorded URL": {
                    "value": {
                      "detail": "The webhook delivery does not have a request URL configured",
                      "code": "webhook_url_missing"
                    }
                  },
                  "Resend failed": {
                    "value": {
                      "detail": "Error processing webhook resend: Invalid webhook data format",
                      "code": "webhook_resend_error"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Kunci API telah kedaluwarsa: kunci ini dibuat dengan tanggal kedaluwarsa yang telah lewat. Kunci yang salah atau dicabut juga menghasilkan `401`; kunci yang tidak ada menghasilkan `403`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "Pesan kesalahan yang mudah dibaca manusia."
                    }
                  }
                },
                "examples": {
                  "Expired key": {
                    "value": {
                      "detail": "This API key has expired."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Permintaan tidak diizinkan. Tidak adanya `x-api-key`, atau kunci yang tidak valid atau dicabut, akan menghasilkan `Authentication credentials were not provided or are invalid.` Kunci dari aplikasi lain akan menghasilkan `You do not have permission to perform this action.` Kunci dengan cakupan terbatas tanpa akses yang dibutuhkan endpoint ini akan menghasilkan pesan yang menyebutkan akses yang hilang, dan kunci yang digunakan dari luar daftar izin IP-nya akan menghasilkan `This API key can't be used from this IP address.` `sessionId` yang tidak dikenal akan mengembalikan `404` sebelum kredensial diperiksa.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "Pesan kesalahan yang mudah dibaca manusia."
                    }
                  }
                },
                "examples": {
                  "Missing or invalid key": {
                    "value": {
                      "detail": "Authentication credentials were not provided or are invalid."
                    }
                  },
                  "Key of another application": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Scoped key without webhooks write": {
                    "value": {
                      "detail": "This API key has no write access to webhooks."
                    }
                  },
                  "Scoped key without decisions read": {
                    "value": {
                      "detail": "This API key has no read access to decisions."
                    }
                  },
                  "Outside the IP allowlist": {
                    "value": {
                      "detail": "This API key can't be used from this IP address."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Sesi tidak ada atau telah dihapus (`Not found.`, dikembalikan sebelum kredensial diperiksa), atau berada di luar batas alur kerja atau status dari kunci dengan cakupan terbatas (`Session not found.`). Pengiriman yang tidak ada, milik sesi lain, atau tidak lagi tersedia mengembalikan `Webhook log not found`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "Pesan kesalahan yang mudah dibaca manusia."
                    }
                  }
                },
                "examples": {
                  "Unknown session": {
                    "value": {
                      "detail": "Not found."
                    }
                  },
                  "Outside the key's limits": {
                    "value": {
                      "detail": "Session not found."
                    }
                  },
                  "Delivery not in this session": {
                    "value": {
                      "detail": "Webhook log not found"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Batas laju terlampaui: lebih dari 300 permintaan tulis (POST, PATCH, PUT, DELETE) dalam jendela satu menit saat ini untuk kunci API ini. Tunggu `Retry-After` detik sebelum mencoba lagi.",
            "headers": {
              "Retry-After": {
                "description": "Detik untuk menunggu sebelum mencoba lagi.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "example": 30
                }
              },
              "X-RateLimit-Limit": {
                "description": "Permintaan yang diizinkan dalam jendela satu menit (300).",
                "schema": {
                  "type": "integer",
                  "example": 300
                }
              },
              "X-RateLimit-Remaining": {
                "description": "Permintaan tersisa dalam jendela saat ini.",
                "schema": {
                  "type": "integer",
                  "example": 0
                }
              },
              "X-RateLimit-Reset": {
                "description": "Waktu Unix (detik) saat jendela saat ini direset.",
                "schema": {
                  "type": "integer",
                  "example": 1792056120
                }
              },
              "X-RateLimit-Scope": {
                "description": "Nama anggaran yang terlampaui.",
                "schema": {
                  "type": "string",
                  "example": "generic-write"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "Pesan kesalahan yang mudah dibaca manusia."
                    }
                  }
                },
                "examples": {
                  "Throttled": {
                    "value": {
                      "detail": "Write request rate limit exceeded. You can make up to 300 requests per minute."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/session/{sessionId}/events/": {
      "get": {
        "summary": "Mencantumkan daftar event sesi",
        "description": "Baca linimasa peristiwa dari satu sesi verifikasi, terbaru lebih dahulu berdasarkan `sent_at`: layar yang dilihat pengguna, tombol dan unggahan, percobaan yang gagal, perubahan status dan langkah fitur, serta pelacakan rute alur kerja. Berfungsi untuk ID sesi Verifikasi Pengguna (KYC) dan Verifikasi Bisnis (KYB). Event disimpan secara asinkron, sehingga event baru memerlukan waktu beberapa detik untuk muncul. Hasil dipaginasi dengan `limit` dan `offset`; ikuti `next` hingga bernilai `null`. Kunci API dengan pembatasan cakupan memerlukan `sessions: read` dan `decisions: read`, dan tanpa `media: read` kunci tersebut menerima `file_url` sebagai `null`. Event perutean dijelaskan di [Ambil sesi](https://docs.didit.me/id/sessions-api/retrieve-session).",
        "operationId": "get_v3_session_events",
        "x-didit-sdk": {
          "resource": "sessions",
          "method": "list_events",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Sessions"
        ],
        "parameters": [
          {
            "name": "sessionId",
            "in": "path",
            "required": true,
            "description": "UUID sesi verifikasi (`session_id` yang dikembalikan oleh `POST /v3/session/`). Menerima ID sesi Verifikasi Pengguna (KYC) dan Verifikasi Bisnis (KYB): server mencari ID tersebut di kedua jenis sesi. Harus berupa UUID dengan format yang benar; nilai yang salah format tidak cocok dengan rute dan mengembalikan HTML `404`.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "11111111-2222-3333-4444-555555555555"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Jumlah event maksimum per halaman. Defaultnya 50. Nilai di bawah 1 atau nilai non-numerik akan dialihkan ke 50; nilai di atas 1.000.000 mengembalikan `400`.",
            "schema": {
              "type": "integer",
              "default": 50,
              "minimum": 1,
              "maximum": 1000000,
              "example": 50
            }
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "description": "Jumlah hasil yang dilewati sebelum hasil pertama yang dikembalikan. Default-nya 0; nilai negatif atau non-numerik akan kembali ke 0, nilai di atas 1.000.000 mengembalikan `400`. Disarankan mengikuti URL `next` dan `previous`.",
            "schema": {
              "type": "integer",
              "default": 0,
              "minimum": 0,
              "maximum": 1000000,
              "example": 0
            }
          },
          {
            "name": "ordering",
            "in": "query",
            "required": false,
            "description": "Penggantian pengurutan opsional. Urutan default adalah `-sent_at`. Berikan nama kolom hasil (misalnya `sent_at`, `created_at`, `event_type`, `feature_step`, atau `step`) untuk mengurutkan secara naik, tambahkan awalan `-` untuk mengurutkan secara turun, dan pisahkan beberapa kolom dengan tanda koma. Kolom yang tidak dikenal akan diabaikan.",
            "schema": {
              "type": "string",
              "example": "sent_at"
            }
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/session/11111111-2222-3333-4444-555555555555/events/?limit=50' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nfor item in client.sessions.list_events(\n    \"11111111-2222-3333-4444-555555555555\",\n):\n    print(item)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nfor await (const item of didit.sessions.listEvents(\"11111111-2222-3333-4444-555555555555\")) {\n  console.log(item);\n}"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\niter := client.Sessions.ListEventsAutoPaging(ctx, \"11111111-2222-3333-4444-555555555555\", didit.SessionsListEventsParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nfor (var item : client.sessions().listEvents(\"11111111-2222-3333-4444-555555555555\")) {\n    System.out.println(item);\n}"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\nforeach ($didit->sessions->listEvents('11111111-2222-3333-4444-555555555555') as $item) {\n    print_r($item->toArray());\n}"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.sessions.list_events(\"11111111-2222-3333-4444-555555555555\").auto_paging_each do |item|\n  puts item.to_h\nend"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.Sessions.ListEventsAsync(\"11111111-2222-3333-4444-555555555555\"))\n{\n    Console.WriteLine(JsonSerializer.Serialize(item));\n}"
          }
        ],
        "responses": {
          "200": {
            "description": "Satu halaman event sesi, terbaru lebih dahulu.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "count",
                    "next",
                    "previous",
                    "results"
                  ],
                  "properties": {
                    "count": {
                      "type": "integer",
                      "description": "Jumlah total event dari sesi."
                    },
                    "next": {
                      "type": "string",
                      "format": "uri",
                      "nullable": true,
                      "description": "URL halaman berikutnya, atau `null` pada halaman terakhir."
                    },
                    "previous": {
                      "type": "string",
                      "format": "uri",
                      "nullable": true,
                      "description": "URL halaman sebelumnya, atau `null` pada halaman pertama."
                    },
                    "results": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/SessionEvent"
                      }
                    }
                  }
                },
                "examples": {
                  "Completed session": {
                    "value": {
                      "count": 3,
                      "next": null,
                      "previous": null,
                      "results": [
                        {
                          "uuid": "aaaaaaaa-1111-2222-3333-444444444444",
                          "event_type": "SESSION_STATUS_CHANGED",
                          "created_at": "2026-09-14T10:02:13.904512Z",
                          "component": null,
                          "feature_step": null,
                          "step": null,
                          "details": {
                            "old_status": "In Progress",
                            "current_status": "Approved"
                          },
                          "ip_address": null,
                          "user_agent": null,
                          "device_info": null,
                          "file_url": null,
                          "sent_at": 1789380131482
                        },
                        {
                          "uuid": "bbbbbbbb-1111-2222-3333-444444444444",
                          "event_type": "FEATURE_STEP_CHANGED",
                          "created_at": "2026-09-14T10:01:49.210377Z",
                          "component": null,
                          "feature_step": null,
                          "step": null,
                          "details": {
                            "old_feature_step": "OCR",
                            "current_feature_step": "LIVENESS"
                          },
                          "ip_address": null,
                          "user_agent": null,
                          "device_info": null,
                          "file_url": null,
                          "sent_at": 1789380107103
                        },
                        {
                          "uuid": "cccccccc-1111-2222-3333-444444444444",
                          "event_type": "STEP_RENDERED",
                          "created_at": "2026-09-14T10:01:00.581930Z",
                          "component": "DocumentCapture",
                          "feature_step": "OCR",
                          "step": "DOCUMENT_CAPTURE_FRONT",
                          "details": {},
                          "ip_address": "203.0.113.24",
                          "user_agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 18_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.5 Mobile/15E148 Safari/604.1",
                          "device_info": {
                            "device_model": "iPhone"
                          },
                          "file_url": null,
                          "sent_at": 1789380058776
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "`limit` atau `offset` berada di atas 1,000,000. Bagian body adalah array JSON dengan satu pesan.",
            "content": {
              "application/json": {
                "examples": {
                  "Limit too large": {
                    "summary": "limit=2000000",
                    "value": [
                      "limit must not exceed 1000000."
                    ]
                  },
                  "Offset too large": {
                    "summary": "offset=2000000",
                    "value": [
                      "offset must not exceed 1000000."
                    ]
                  }
                },
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Kunci API dengan cakupan terbatas telah kedaluwarsa. Ini satu-satunya kasus yang mengembalikan `401`: kunci yang hilang, tidak valid, atau dicabut mengembalikan `403`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "Pesan kesalahan yang mudah dibaca manusia."
                    }
                  }
                },
                "examples": {
                  "Expired key": {
                    "summary": "Tanggal kedaluwarsa kunci telah lewat",
                    "value": {
                      "detail": "This API key has expired."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Kegagalan autentikasi atau otorisasi. Kunci yang hilang mengembalikan `403`, begitu juga dengan kunci dari aplikasi lain, kunci dengan cakupan tanpa izin yang dibutuhkan endpoint ini, dan permintaan dari luar daftar izin IP kunci tersebut; kunci yang salah, dicabut, atau kedaluwarsa mengembalikan `401`. Bedakan kegagalan tersebut berdasarkan `detail`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "Pesan kesalahan yang mudah dibaca manusia."
                    }
                  }
                },
                "examples": {
                  "Missing or invalid credentials": {
                    "summary": "Tidak ada header x-api-key, atau kunci gagal divalidasi",
                    "value": {
                      "detail": "Authentication credentials were not provided or are invalid."
                    }
                  },
                  "Other application": {
                    "summary": "Kunci valid milik aplikasi yang berbeda dari sesi",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Scoped key without sessions read": {
                    "summary": "Kunci ber-scope tidak memiliki sessions: read",
                    "value": {
                      "detail": "This API key has no read access to sessions."
                    }
                  },
                  "Scoped key without decisions read": {
                    "summary": "Kunci ber-scope tidak memiliki decisions: read",
                    "value": {
                      "detail": "This API key has no read access to decisions."
                    }
                  },
                  "IP not allowed": {
                    "summary": "Permintaan dari luar daftar izin IP kunci",
                    "value": {
                      "detail": "This API key can't be used from this IP address."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Sesi tidak ada, telah dihapus, atau berada di luar alur kerja kunci dengan cakupan terbatas atau batas yang hanya berlaku untuk sesi berstatus disetujui. Pencarian sesi berjalan sebelum pemeriksaan kredensial, sehingga `sessionId` yang tidak dikenal mengembalikan `404` bahkan tanpa kunci yang valid.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "Pesan kesalahan yang mudah dibaca manusia."
                    }
                  }
                },
                "examples": {
                  "Unknown session": {
                    "summary": "Tidak ada sesi dengan ID ini, atau telah dihapus",
                    "value": {
                      "detail": "Not found."
                    }
                  },
                  "Outside key limits": {
                    "summary": "Sesi berada di luar alur kerja atau batas yang hanya berlaku untuk sesi yang disetujui milik kunci dengan cakupan terbatas",
                    "value": {
                      "detail": "Session not found."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Batas laju terlampaui: 600 permintaan GET per menit per kunci API. Tunggu `Retry-After` detik sebelum mencoba lagi; header `X-RateLimit-*` menampilkan anggaran yang tersedia.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "Pesan kesalahan yang mudah dibaca manusia."
                    }
                  }
                },
                "examples": {
                  "Rate limited": {
                    "summary": "Anggaran untuk menit saat ini habis",
                    "value": {
                      "detail": "GET request rate limit exceeded. You can make up to 600 requests per minute."
                    }
                  }
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Detik untuk menunggu sebelum mencoba lagi.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "example": 30
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/session/{sessionId}/aml-screening-history/": {
      "get": {
        "summary": "Daftar riwayat skrining AML",
        "description": "Daftar setiap skrining ulang pemantauan berkelanjutan yang telah selesai dari pemeriksaan AML suatu sesi, terbaru lebih dahulu berdasarkan `completed_at`, termasuk proses di mana tidak ada yang berubah: alert, entri aktivitas, dan webhook hanya terpicu saat hasil berubah, sehingga riwayat ini menjadi bukti bahwa subjek yang bersih tetap diskrining. Berfungsi untuk ID sesi KYC dan KYB; teruskan `node_id` jika sesi menjalankan lebih dari satu langkah AML. Hanya skrining ulang pemantauan berkelanjutan yang dicantumkan (skrining pertama adalah bagian dari keputusan sesi) dan proses dari sebelum riwayat ini ada tidak direkonstruksi, sehingga sesi tanpa pemantauan berkelanjutan mengembalikan daftar kosong. `count` akurat hingga 100 dan dibatasi maksimum 100 di atasnya, jadi ikuti `next` hingga bernilai `null`. Teruskan `month` untuk membaca satu bulan kalender sekaligus. Kunci API yang dibatasi cakupannya memerlukan `decisions: read`; lihat [Pemantauan AML Berkelanjutan](https://docs.didit.me/id/core-technology/aml-screening/continuous-monitoring-aml-screening).",
        "operationId": "get_v3_session_aml_screening_history",
        "x-didit-sdk": {
          "resource": "sessions",
          "method": "list_aml_screening_history",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Sessions"
        ],
        "parameters": [
          {
            "name": "sessionId",
            "in": "path",
            "required": true,
            "description": "UUID sesi verifikasi (`session_id` yang dikembalikan oleh `POST /v3/session/`). Menerima ID sesi Verifikasi Pengguna (KYC) dan Verifikasi Bisnis (KYB): server mencari ID tersebut di kedua jenis sesi. Harus berupa UUID dengan format yang benar; nilai yang salah format tidak cocok dengan rute dan mengembalikan HTML `404`.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "11111111-2222-3333-4444-555555555555"
            }
          },
          {
            "name": "node_id",
            "in": "query",
            "required": false,
            "description": "ID node graf alur kerja dari pemeriksaan AML. Hanya diperlukan jika sesi menjalankan lebih dari satu langkah AML; jika tidak diisi, pemeriksaan AML terbaru yang akan digunakan. Node yang tidak dikenal akan mengembalikan `404`.",
            "schema": {
              "type": "string",
              "example": "feature_aml_1"
            }
          },
          {
            "name": "month",
            "in": "query",
            "required": false,
            "description": "Bulan kalender UTC dalam format `YYYY-MM`. Hanya skrining yang selesai pada bulan tersebut yang dikembalikan; tanpa parameter ini, setiap bulan akan dikembalikan. Format bulan yang salah mengembalikan `400`.",
            "schema": {
              "type": "string",
              "pattern": "^\\d{4}-(0[1-9]|1[0-2])$",
              "example": "2026-09"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Jumlah eksekusi skrining maksimum per halaman. Defaultnya 50. Nilai di bawah 1 atau nilai non-numerik akan dialihkan ke 50; nilai di atas 1.000.000 mengembalikan `400`.",
            "schema": {
              "type": "integer",
              "default": 50,
              "minimum": 1,
              "maximum": 1000000,
              "example": 50
            }
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "description": "Jumlah hasil yang dilewati sebelum hasil pertama yang dikembalikan. Default-nya 0; nilai negatif atau non-numerik akan kembali ke 0, nilai di atas 1.000.000 mengembalikan `400`. Disarankan mengikuti URL `next` dan `previous`.",
            "schema": {
              "type": "integer",
              "default": 0,
              "minimum": 0,
              "maximum": 1000000,
              "example": 0
            }
          },
          {
            "name": "ordering",
            "in": "query",
            "required": false,
            "description": "Penggantian pengurutan opsional. Urutan default adalah `-completed_at`. Berikan nama kolom hasil (misalnya `completed_at`, `started_at`, `outcome`, atau `score`) untuk mengurutkan secara naik, tambahkan awalan `-` untuk mengurutkan secara turun, dan pisahkan beberapa kolom dengan tanda koma. Kolom yang tidak dikenal akan diabaikan.",
            "schema": {
              "type": "string",
              "example": "completed_at"
            }
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/session/11111111-2222-3333-4444-555555555555/aml-screening-history/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nfor item in client.sessions.list_aml_screening_history(\n    \"11111111-2222-3333-4444-555555555555\",\n):\n    print(item)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nfor await (const item of didit.sessions.listAmlScreeningHistory(\"11111111-2222-3333-4444-555555555555\")) {\n  console.log(item);\n}"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\niter := client.Sessions.ListAMLScreeningHistoryAutoPaging(ctx, \"11111111-2222-3333-4444-555555555555\", didit.SessionsListAMLScreeningHistoryParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nfor (var item : client.sessions().listAmlScreeningHistory(\"11111111-2222-3333-4444-555555555555\")) {\n    System.out.println(item);\n}"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\nforeach ($didit->sessions->listAmlScreeningHistory('11111111-2222-3333-4444-555555555555') as $item) {\n    print_r($item->toArray());\n}"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.sessions.list_aml_screening_history(\"11111111-2222-3333-4444-555555555555\").auto_paging_each do |item|\n  puts item.to_h\nend"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.Sessions.ListAmlScreeningHistoryAsync(\"11111111-2222-3333-4444-555555555555\"))\n{\n    Console.WriteLine(JsonSerializer.Serialize(item));\n}"
          }
        ],
        "responses": {
          "200": {
            "description": "Satu halaman eksekusi skrining, terbaru lebih dahulu.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "count",
                    "next",
                    "previous",
                    "results"
                  ],
                  "properties": {
                    "count": {
                      "type": "integer",
                      "maximum": 100,
                      "description": "Jumlah eksekusi, tepat hingga 100 dan dibatasi maksimal 100 di atasnya."
                    },
                    "next": {
                      "type": "string",
                      "format": "uri",
                      "nullable": true,
                      "description": "URL halaman berikutnya, atau `null` pada halaman terakhir."
                    },
                    "previous": {
                      "type": "string",
                      "format": "uri",
                      "nullable": true,
                      "description": "URL halaman sebelumnya, atau `null` pada halaman pertama."
                    },
                    "results": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/AMLScreeningRun"
                      }
                    }
                  }
                },
                "examples": {
                  "Monitored subject": {
                    "value": {
                      "count": 2,
                      "next": null,
                      "previous": null,
                      "results": [
                        {
                          "uuid": "dddddddd-1111-2222-3333-444444444444",
                          "run_id": "aaaaaaaa-1111-2222-3333-444444444444",
                          "completed_at": "2026-09-14T04:12:33.481207Z",
                          "started_at": "2026-09-14T04:00:01.002311Z",
                          "outcome": "NO_CHANGE",
                          "trigger": "ONGOING_MONITORING",
                          "provider": "aml_data_source",
                          "status": "Approved",
                          "score": 0.0,
                          "total_hits": 0,
                          "new_hits": 0,
                          "entities_screened": 1,
                          "dataset_freshness": {
                            "captured_at": "2026-09-14T03:58:02.114820+00:00",
                            "provider": "aml_data_source",
                            "catalog_version": "2026-09-13",
                            "sources": {
                              "sanctions": {
                                "last_updated_at": "2026-09-13T21:10:00+00:00",
                                "oldest_updated_at": "2026-09-11T06:00:00+00:00",
                                "dataset_count": 120,
                                "dated_dataset_count": 120
                              },
                              "pep": {
                                "last_updated_at": "2026-09-13T08:00:00+00:00",
                                "oldest_updated_at": null,
                                "dataset_count": 45,
                                "dated_dataset_count": 44
                              },
                              "warnings": {
                                "last_updated_at": "2026-09-12T18:45:00+00:00",
                                "oldest_updated_at": "2026-09-01T00:00:00+00:00",
                                "dataset_count": 30,
                                "dated_dataset_count": 30
                              }
                            }
                          }
                        },
                        {
                          "uuid": "eeeeeeee-1111-2222-3333-444444444444",
                          "run_id": "bbbbbbbb-1111-2222-3333-444444444444",
                          "completed_at": "2026-09-13T04:11:58.020914Z",
                          "started_at": "2026-09-13T04:00:00.871022Z",
                          "outcome": "FAILED",
                          "trigger": "ONGOING_MONITORING",
                          "provider": "aml_data_source",
                          "status": "Approved",
                          "score": 0.0,
                          "total_hits": 0,
                          "new_hits": null,
                          "entities_screened": 0,
                          "dataset_freshness": null
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "`limit` atau `offset` berada di atas 1,000,000 (array JSON dengan satu pesan), atau `month` bukan bulan kalender `YYYY-MM` (objek dengan kunci `month`).",
            "content": {
              "application/json": {
                "examples": {
                  "Limit too large": {
                    "summary": "limit=2000000",
                    "value": [
                      "limit must not exceed 1000000."
                    ]
                  },
                  "Offset too large": {
                    "summary": "offset=2000000",
                    "value": [
                      "offset must not exceed 1000000."
                    ]
                  },
                  "Malformed month": {
                    "summary": "month=2026-13",
                    "value": {
                      "month": [
                        "Not a calendar month. Use YYYY-MM."
                      ]
                    }
                  }
                },
                "schema": {
                  "oneOf": [
                    {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    {
                      "type": "object",
                      "properties": {
                        "month": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Kunci API dengan cakupan terbatas telah kedaluwarsa. Ini satu-satunya kasus yang mengembalikan `401`: kunci yang hilang, tidak valid, atau dicabut mengembalikan `403`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "Pesan kesalahan yang mudah dibaca manusia."
                    }
                  }
                },
                "examples": {
                  "Expired key": {
                    "summary": "Tanggal kedaluwarsa kunci telah lewat",
                    "value": {
                      "detail": "This API key has expired."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Kegagalan autentikasi atau otorisasi. Kunci yang hilang mengembalikan `403`, begitu juga dengan kunci dari aplikasi lain, kunci dengan cakupan tanpa izin yang dibutuhkan endpoint ini, dan permintaan dari luar daftar izin IP kunci tersebut; kunci yang salah, dicabut, atau kedaluwarsa mengembalikan `401`. Bedakan kegagalan tersebut berdasarkan `detail`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "Pesan kesalahan yang mudah dibaca manusia."
                    }
                  }
                },
                "examples": {
                  "Missing or invalid credentials": {
                    "summary": "Tidak ada header x-api-key, atau kunci gagal divalidasi",
                    "value": {
                      "detail": "Authentication credentials were not provided or are invalid."
                    }
                  },
                  "Other application": {
                    "summary": "Kunci valid milik aplikasi yang berbeda dari sesi",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Scoped key without decisions read": {
                    "summary": "Kunci ber-scope tidak memiliki decisions: read",
                    "value": {
                      "detail": "This API key has no read access to decisions."
                    }
                  },
                  "IP not allowed": {
                    "summary": "Permintaan dari luar daftar izin IP kunci",
                    "value": {
                      "detail": "This API key can't be used from this IP address."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Sesi tidak ada, telah dihapus, atau berada di luar batas kunci dengan cakupan terbatas, atau tidak memiliki pemeriksaan AML (untuk `node_id` yang diberikan). Pencarian sesi berjalan sebelum pemeriksaan kredensial, sehingga `sessionId` yang tidak dikenal mengembalikan `404` bahkan tanpa kunci yang valid.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "Pesan kesalahan yang mudah dibaca manusia."
                    }
                  }
                },
                "examples": {
                  "Unknown session": {
                    "summary": "Tidak ada sesi dengan ID ini, atau telah dihapus",
                    "value": {
                      "detail": "Not found."
                    }
                  },
                  "Outside key limits": {
                    "summary": "Sesi berada di luar batas kunci dengan cakupan terbatas (juga dikembalikan untuk sesi yang baru saja dihapus)",
                    "value": {
                      "detail": "Session not found."
                    }
                  },
                  "No AML check": {
                    "summary": "Sesi tidak pernah menjalankan langkah AML",
                    "value": {
                      "detail": "The session does not have an AML check."
                    }
                  },
                  "No AML check for node": {
                    "summary": "node_id tidak cocok dengan pemeriksaan AML pada sesi tersebut",
                    "value": {
                      "detail": "The session does not have an AML check for node 'feature_aml_2'."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Batas laju terlampaui: 600 permintaan GET per menit per kunci API. Tunggu `Retry-After` detik sebelum mencoba lagi; header `X-RateLimit-*` menampilkan anggaran yang tersedia.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "Pesan kesalahan yang mudah dibaca manusia."
                    }
                  }
                },
                "examples": {
                  "Rate limited": {
                    "summary": "Anggaran untuk menit saat ini habis",
                    "value": {
                      "detail": "GET request rate limit exceeded. You can make up to 600 requests per minute."
                    }
                  }
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Detik untuk menunggu sebelum mencoba lagi.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "example": 30
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/session/{sessionId}/aml-screening-history/export/": {
      "get": {
        "summary": "Ekspor riwayat skrining AML sebagai CSV",
        "description": "Unduh riwayat pemantauan berkelanjutan yang sama seperti `GET /v3/session/{sessionId}/aml-screening-history/` sebagai file CSV, satu baris per skrining ulang yang selesai, dari yang terbaru terlebih dahulu, siap diserahkan kepada auditor. File dialirkan secara utuh (tanpa paginasi) dan dimulai dengan baris header; sel kosong berarti tidak diketahui, tanggal dataset tidak pernah diestimasi, dan nilai yang akan memulai rumus spreadsheet diawali dengan tanda petik tunggal. Berfungsi untuk ID sesi KYC dan KYB; berikan `node_id` jika sesi menjalankan lebih dari satu langkah AML. Berikan `month` untuk mengekspor satu bulan kalender. Kesalahan dikembalikan sebagai JSON, bukan CSV. Kunci API dengan cakupan memerlukan `decisions: read` dan `media: read`: karena respons berupa file, kunci tanpa `media: read` akan menerima `403`.",
        "operationId": "get_v3_session_aml_screening_history_export",
        "x-didit-sdk": {
          "resource": "sessions",
          "method": "export_aml_screening_history",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Sessions"
        ],
        "parameters": [
          {
            "name": "sessionId",
            "in": "path",
            "required": true,
            "description": "UUID sesi verifikasi (`session_id` yang dikembalikan oleh `POST /v3/session/`). Menerima ID sesi Verifikasi Pengguna (KYC) dan Verifikasi Bisnis (KYB): server mencari ID tersebut di kedua jenis sesi. Harus berupa UUID dengan format yang benar; nilai yang salah format tidak cocok dengan rute dan mengembalikan HTML `404`.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "11111111-2222-3333-4444-555555555555"
            }
          },
          {
            "name": "node_id",
            "in": "query",
            "required": false,
            "description": "ID node graf alur kerja dari pemeriksaan AML. Hanya diperlukan jika sesi menjalankan lebih dari satu langkah AML; jika tidak diisi, pemeriksaan AML terbaru yang akan digunakan. Node yang tidak dikenal akan mengembalikan `404`.",
            "schema": {
              "type": "string",
              "example": "feature_aml_1"
            }
          },
          {
            "name": "month",
            "in": "query",
            "required": false,
            "description": "Bulan kalender UTC dalam format `YYYY-MM`. Hanya skrining yang selesai pada bulan tersebut yang dikembalikan; tanpa parameter ini, setiap bulan akan dikembalikan. Format bulan yang salah mengembalikan `400`.",
            "schema": {
              "type": "string",
              "pattern": "^\\d{4}-(0[1-9]|1[0-2])$",
              "example": "2026-09"
            }
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/session/11111111-2222-3333-4444-555555555555/aml-screening-history/export/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -o aml-screening-history.csv"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\ncontent = client.sessions.export_aml_screening_history(\n    \"11111111-2222-3333-4444-555555555555\",\n)\nwith open(\"download.csv\", \"wb\") as file:\n    file.write(content)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import { writeFile } from \"node:fs/promises\";\nimport Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst content = await didit.sessions.exportAmlScreeningHistory(\"11111111-2222-3333-4444-555555555555\");\nawait writeFile(\"download.csv\", Buffer.from(await content.arrayBuffer()));"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresp, err := client.Sessions.ExportAMLScreeningHistory(ctx, \"11111111-2222-3333-4444-555555555555\", didit.SessionsExportAMLScreeningHistoryParams{})\nif err != nil {\n\tlog.Fatal(err)\n}\ndefer resp.Body.Close()\nfile, err := os.Create(\"download.csv\")\nif err != nil {\n\tlog.Fatal(err)\n}\ndefer file.Close()\nif _, err := io.Copy(file, resp.Body); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.nio.file.Path;\nimport me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nclient.sessions().exportAmlScreeningHistory(\"11111111-2222-3333-4444-555555555555\")\n        .writeTo(Path.of(\"download.csv\"));"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$content = $didit->sessions->exportAmlScreeningHistory('11111111-2222-3333-4444-555555555555');\n$content->saveTo('download.csv');"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ncontent = didit.sessions.export_aml_screening_history(\"11111111-2222-3333-4444-555555555555\")\nFile.binwrite(\"download.csv\", content)"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar content = await client.Sessions.ExportAmlScreeningHistoryAsync(\"11111111-2222-3333-4444-555555555555\");\nawait content.SaveToAsync(\"download.csv\");"
          }
        ],
        "responses": {
          "200": {
            "description": "File CSV, dialirkan sebagai `text/csv` dengan pemisah baris CRLF. Kolom, secara berurutan: `screened_at` (saat skrining ulang selesai), `outcome` (`NO_CHANGE`, `CHANGED`, atau `FAILED`), `provider` (pengidentifikasi opak dari sumber data AML; jangan gunakan nilainya untuk menentukan percabangan), `aml_status`, `aml_score`, `total_hits`, `datasets_captured_at`, `datasets_sanctions_last_updated_at`, `datasets_pep_last_updated_at`, `datasets_warnings_last_updated_at`, `datasets_adverse_media_last_updated_at`, `datasets_catalog_version`, `run_id` (proses pemantauan), `entities_screened` (`1`, atau `0` untuk proses yang gagal) dan `new_hits` (kosong jika tidak diketahui). Format tanggal adalah ISO 8601 dengan offset UTC. Sesi yang belum memiliki skrining ulang hanya mengembalikan baris header.",
            "headers": {
              "Content-Disposition": {
                "description": "`attachment; filename=\"aml-screening-history-{sessionId}.csv\"`, atau `aml-screening-history-{sessionId}-{month}.csv` ketika `month` diteruskan.",
                "schema": {
                  "type": "string",
                  "example": "attachment; filename=\"aml-screening-history-11111111-2222-3333-4444-555555555555.csv\""
                }
              }
            },
            "content": {
              "text/csv": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                },
                "example": "screened_at,outcome,provider,aml_status,aml_score,total_hits,datasets_captured_at,datasets_sanctions_last_updated_at,datasets_pep_last_updated_at,datasets_warnings_last_updated_at,datasets_adverse_media_last_updated_at,datasets_catalog_version,run_id,entities_screened,new_hits\r\n2026-09-14T04:12:33.481207+00:00,NO_CHANGE,aml_data_source,Approved,0.0,0,2026-09-14T03:58:02.114820+00:00,2026-09-13T21:10:00+00:00,2026-09-13T08:00:00+00:00,2026-09-12T18:45:00+00:00,,2026-09-13,aaaaaaaa-1111-2222-3333-444444444444,1,0\r\n2026-09-13T04:11:58.020914+00:00,FAILED,aml_data_source,Approved,0.0,0,,,,,,,bbbbbbbb-1111-2222-3333-444444444444,0,\r\n"
              }
            }
          },
          "400": {
            "description": "`month` bukan bulan kalender `YYYY-MM`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "month": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                },
                "examples": {
                  "Malformed month": {
                    "summary": "month=2026-13",
                    "value": {
                      "month": [
                        "Not a calendar month. Use YYYY-MM."
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Kunci API dengan cakupan terbatas telah kedaluwarsa. Ini satu-satunya kasus yang mengembalikan `401`: kunci yang hilang, tidak valid, atau dicabut mengembalikan `403`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "Pesan kesalahan yang mudah dibaca manusia."
                    }
                  }
                },
                "examples": {
                  "Expired key": {
                    "summary": "Tanggal kedaluwarsa kunci telah lewat",
                    "value": {
                      "detail": "This API key has expired."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Kegagalan autentikasi atau otorisasi. Kunci yang hilang mengembalikan `403`, begitu juga dengan kunci dari aplikasi lain, kunci dengan cakupan tanpa izin yang dibutuhkan endpoint ini, dan permintaan dari luar daftar izin IP kunci tersebut; kunci yang salah, dicabut, atau kedaluwarsa mengembalikan `401`. Bedakan kegagalan tersebut berdasarkan `detail`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "Pesan kesalahan yang mudah dibaca manusia."
                    }
                  }
                },
                "examples": {
                  "Missing or invalid credentials": {
                    "summary": "Tidak ada header x-api-key, atau kunci gagal divalidasi",
                    "value": {
                      "detail": "Authentication credentials were not provided or are invalid."
                    }
                  },
                  "Other application": {
                    "summary": "Kunci valid milik aplikasi yang berbeda dari sesi",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Scoped key without decisions read": {
                    "summary": "Kunci ber-scope tidak memiliki decisions: read",
                    "value": {
                      "detail": "This API key has no read access to decisions."
                    }
                  },
                  "Scoped key without media read": {
                    "summary": "Kunci ber-scope tidak memiliki media: read (respons berupa file)",
                    "value": {
                      "detail": "This API key has no read access to media."
                    }
                  },
                  "IP not allowed": {
                    "summary": "Permintaan dari luar daftar izin IP kunci",
                    "value": {
                      "detail": "This API key can't be used from this IP address."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Sesi tidak ada, telah dihapus, atau berada di luar batas kunci dengan cakupan terbatas, atau tidak memiliki pemeriksaan AML (untuk `node_id` yang diberikan). Pencarian sesi berjalan sebelum pemeriksaan kredensial, sehingga `sessionId` yang tidak dikenal mengembalikan `404` bahkan tanpa kunci yang valid.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "Pesan kesalahan yang mudah dibaca manusia."
                    }
                  }
                },
                "examples": {
                  "Unknown session": {
                    "summary": "Tidak ada sesi dengan ID ini, atau telah dihapus",
                    "value": {
                      "detail": "Not found."
                    }
                  },
                  "Outside key limits": {
                    "summary": "Sesi berada di luar batas kunci dengan cakupan terbatas (juga dikembalikan untuk sesi yang baru saja dihapus)",
                    "value": {
                      "detail": "Session not found."
                    }
                  },
                  "No AML check": {
                    "summary": "Sesi tidak pernah menjalankan langkah AML",
                    "value": {
                      "detail": "The session does not have an AML check."
                    }
                  },
                  "No AML check for node": {
                    "summary": "node_id tidak cocok dengan pemeriksaan AML pada sesi tersebut",
                    "value": {
                      "detail": "The session does not have an AML check for node 'feature_aml_2'."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Batas laju terlampaui: 600 permintaan GET per menit per kunci API. Tunggu `Retry-After` detik sebelum mencoba lagi; header `X-RateLimit-*` menampilkan anggaran yang tersedia.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "Pesan kesalahan yang mudah dibaca manusia."
                    }
                  }
                },
                "examples": {
                  "Rate limited": {
                    "summary": "Anggaran untuk menit saat ini habis",
                    "value": {
                      "detail": "GET request rate limit exceeded. You can make up to 600 requests per minute."
                    }
                  }
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Detik untuk menunggu sebelum mencoba lagi.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "example": 30
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/session/{sessionId}/add-images/": {
      "patch": {
        "summary": "Tambahkan gambar ke sesi",
        "description": "Lampirkan satu gambar atau PDF tambahan ke hasil Verifikasi Identitas (`model_type=kyc`) atau Bukti Alamat (`model_type=poa`) dari sesi Verifikasi Pengguna (KYC) yang sudah selesai, misalnya bukti yang dikumpulkan di luar alur. Sesi harus berstatus `Approved`, `Declined`, `In Review`, atau `Kyc Expired` dan membawa hasil yang ditentukan oleh `model_type`; sesi Verifikasi Bisnis (KYB) tidak didukung. Setiap panggilan menambahkan satu file (ke hasil terbaru saat langkah tersebut berjalan lebih dari sekali), mempertahankan file yang ada, dan mencatat entri `FILE_ADDED` di log aktivitas sesi; pengunggahan ini tidak mengirim webhook dan tidak mengubah status sesi. File dikompresi saat diunggah dan dikembalikan di `extra_files` dari keputusan sesi. Endpoint ini dibatasi hingga 10 permintaan per menit per kunci API. Kunci API dengan cakupan membutuhkan `sessions: write`, dan tanpa `media: read` kunci tersebut menerima tautan `extra_files` sebagai `null`.",
        "operationId": "patch_v3_session_add_images",
        "x-didit-sdk": {
          "resource": "sessions",
          "method": "add_images",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Sessions"
        ],
        "parameters": [
          {
            "name": "sessionId",
            "in": "path",
            "required": true,
            "description": "UUID dari sesi Verifikasi Pengguna (KYC) untuk menambahkan file (yaitu `session_id` yang dikembalikan oleh `POST /v3/session/`). ID sesi Verifikasi Bisnis (KYB) akan mengembalikan `404`.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "11111111-2222-3333-4444-555555555555"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "required": [
                  "file",
                  "model_type"
                ],
                "properties": {
                  "file": {
                    "type": "string",
                    "format": "binary",
                    "description": "Gambar atau PDF. Ekstensi yang diizinkan: `jpg`, `jpeg`, `png`, `webp`, `tiff`, `pdf`. Maksimal 15 MB saat diunggah; file kemudian dikompresi dan ditolak dengan `400` jika ukurannya masih lebih besar dari 2 MB (2,097,152 byte). File kosong ditolak."
                  },
                  "model_type": {
                    "type": "string",
                    "enum": [
                      "kyc",
                      "poa"
                    ],
                    "description": "`kyc` menambahkan file ke hasil Verifikasi Identitas, `poa` ke hasil Bukti Alamat.",
                    "example": "kyc"
                  },
                  "file_password": {
                    "type": "string",
                    "description": "Kata sandi untuk PDF terenkripsi. Tanpa kata sandi, atau jika salah, PDF terenkripsi mengembalikan `400`."
                  }
                }
              },
              "example": {
                "file": "(binary)",
                "model_type": "kyc"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X PATCH 'https://verification.didit.me/v3/session/11111111-2222-3333-4444-555555555555/add-images/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -F 'file=@./back-of-id.jpg' \\\n  -F 'model_type=kyc'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.add_images(\n    \"11111111-2222-3333-4444-555555555555\",\n    file=open(\"image.jpg\", \"rb\"),\n    model_type=\"kyc\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit, { fileFromPath } from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.addImages(\"11111111-2222-3333-4444-555555555555\", {\n  file: await fileFromPath(\"image.jpg\"),\n  model_type: \"kyc\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.AddImages(ctx, \"11111111-2222-3333-4444-555555555555\", didit.SessionsAddImagesParams{\n\tFile:      didit.FileFromPath(\"image.jpg\"),\n\tModelType: \"kyc\",\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.nio.file.Path;\nimport me.didit.Didit;\nimport me.didit.types.SessionsAddImagesParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().addImages(\"11111111-2222-3333-4444-555555555555\", SessionsAddImagesParams.builder()\n        .file(Path.of(\"image.jpg\"))\n        .modelType(SessionsAddImagesParams.ModelType.of(\"kyc\"))\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\nuse Didit\\File;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->sessions->addImages('11111111-2222-3333-4444-555555555555', [\n    'file' => File::fromPath('image.jpg'),\n    'model_type' => 'kyc',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.add_images(\n  \"11111111-2222-3333-4444-555555555555\",\n  file: Pathname(\"image.jpg\"),\n  model_type: \"kyc\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.AddImagesAsync(\"11111111-2222-3333-4444-555555555555\", new SessionsAddImagesParams\n{\n    File = FileUpload.FromPath(\"image.jpg\"),\n    ModelType = \"kyc\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "File ditambahkan. Mengembalikan setiap file tambahan dari hasil tersebut, termasuk yang baru.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "extra_files"
                  ],
                  "properties": {
                    "extra_files": {
                      "type": "array",
                      "description": "Tautan presigned berdurasi singkat ke semua file tambahan dari hasil yang dinamai oleh `model_type`, dengan yang terlama terlebih dahulu. Setiap tautan bernilai `null` untuk kunci API dengan cakupan terbatas tanpa `media: read`. Baca tautan baru dari keputusan sesi nanti.",
                      "items": {
                        "type": "string",
                        "format": "uri",
                        "nullable": true
                      }
                    }
                  }
                },
                "example": {
                  "extra_files": [
                    "https://media.example.com/session/11111111-2222-3333-4444-555555555555/kyc-extra-files/66666666-7777-8888-9999-000000000000.jpg?expires=1789383731&signature=abc123"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Kesalahan validasi. Kesalahan kolom diterima sebagai `{\"<field>\": [\"<message>\"]}`; kesalahan PDF terenkripsi sebagai `{\"detail\": \"...\"}`.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing file": {
                    "summary": "Tidak ada bagian file di dalam formulir",
                    "value": {
                      "file": [
                        "No file was submitted."
                      ]
                    }
                  },
                  "Missing model_type": {
                    "summary": "model_type dihilangkan",
                    "value": {
                      "model_type": [
                        "This field is required."
                      ]
                    }
                  },
                  "Invalid model_type": {
                    "summary": "model_type bukan kyc atau poa",
                    "value": {
                      "model_type": [
                        "\"passport\" is not a valid choice."
                      ]
                    }
                  },
                  "File too large": {
                    "summary": "Unggahan melebihi 15 MB",
                    "value": {
                      "file": [
                        "File size should not exceed 15 MB"
                      ]
                    }
                  },
                  "Too large after compression": {
                    "summary": "Masih lebih dari 2 MB setelah kompresi",
                    "value": {
                      "file": [
                        "File size is too big. Max allowed size is 2097152 bytes."
                      ]
                    }
                  },
                  "Encrypted PDF": {
                    "summary": "PDF terenkripsi tanpa file_password",
                    "value": {
                      "detail": "The PDF is encrypted. Please upload a decrypted PDF or a photo instead."
                    }
                  },
                  "Wrong PDF password": {
                    "summary": "file_password tidak dapat membuka PDF",
                    "value": {
                      "detail": "The PDF password is incorrect. Please provide the correct password."
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Kunci API dengan cakupan terbatas telah kedaluwarsa. Ini satu-satunya kasus yang mengembalikan `401`: kunci yang hilang, tidak valid, atau dicabut mengembalikan `403`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "Pesan kesalahan yang mudah dibaca manusia."
                    }
                  }
                },
                "examples": {
                  "Expired key": {
                    "summary": "Tanggal kedaluwarsa kunci telah lewat",
                    "value": {
                      "detail": "This API key has expired."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Kegagalan autentikasi atau otorisasi. Kunci yang hilang mengembalikan `403`, begitu juga dengan kunci dari aplikasi lain, kunci dengan cakupan tanpa izin yang dibutuhkan endpoint ini, dan permintaan dari luar daftar izin IP kunci tersebut; kunci yang salah, dicabut, atau kedaluwarsa mengembalikan `401`. Bedakan kegagalan tersebut berdasarkan `detail`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "Pesan kesalahan yang mudah dibaca manusia."
                    }
                  }
                },
                "examples": {
                  "Missing or invalid credentials": {
                    "summary": "Tidak ada header x-api-key, atau kunci gagal divalidasi",
                    "value": {
                      "detail": "Authentication credentials were not provided or are invalid."
                    }
                  },
                  "Other application": {
                    "summary": "Kunci valid milik aplikasi yang berbeda dari sesi",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Scoped key without sessions write": {
                    "summary": "Kunci ber-scope tidak memiliki sessions: write",
                    "value": {
                      "detail": "This API key has no write access to sessions."
                    }
                  },
                  "IP not allowed": {
                    "summary": "Permintaan dari luar daftar izin IP kunci",
                    "value": {
                      "detail": "This API key can't be used from this IP address."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Sesi tidak ada, telah dihapus, atau berada di luar batas kunci dengan cakupan terbatas; merupakan sesi KYB atau tidak berstatus `Approved`, `Declined`, `In Review`, atau `Kyc Expired`; atau tidak memiliki hasil dari `model_type` yang diminta (diperiksa sebelum file divalidasi). Pencarian sesi berjalan sebelum pemeriksaan kredensial, sehingga `sessionId` yang tidak dikenal mengembalikan `404` bahkan tanpa kunci yang valid.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "Pesan kesalahan yang mudah dibaca manusia."
                    }
                  }
                },
                "examples": {
                  "Unknown session": {
                    "summary": "Tidak ada sesi dengan ID ini, atau telah dihapus",
                    "value": {
                      "detail": "Not found."
                    }
                  },
                  "Outside key limits": {
                    "summary": "Sesi berada di luar alur kerja atau batas yang hanya berlaku untuk sesi yang disetujui milik kunci dengan cakupan terbatas",
                    "value": {
                      "detail": "Session not found."
                    }
                  },
                  "Not eligible": {
                    "summary": "Sesi belum selesai, atau merupakan ID sesi KYB",
                    "value": {
                      "detail": "No Session matches the given query."
                    }
                  },
                  "No ID verification": {
                    "summary": "model_type=kyc pada sesi tanpa Verifikasi Identitas",
                    "value": {
                      "detail": "The session does not have KYC data."
                    }
                  },
                  "No Proof of Address": {
                    "summary": "model_type=poa pada sesi tanpa Bukti Alamat",
                    "value": {
                      "detail": "The session does not have POA data."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Batas laju terlampaui: 10 permintaan penambahan gambar per menit per kunci API (permintaan yang ditolak juga dihitung). Anggaran bersama sebesar 300 permintaan penulisan per menit juga berlaku. Tunggu selama `Retry-After` detik sebelum mencoba lagi; header `X-RateLimit-*` menunjukkan anggaran tersebut.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "Pesan kesalahan yang mudah dibaca manusia."
                    }
                  }
                },
                "examples": {
                  "Rate limited": {
                    "summary": "Anggaran untuk menit saat ini habis",
                    "value": {
                      "detail": "Session add-images rate limit exceeded. You can make up to 10 requests per minute."
                    }
                  }
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Detik untuk menunggu sebelum mencoba lagi.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "example": 30
                }
              }
            }
          },
          "503": {
            "$ref": "#/components/responses/DocumentProcessingBusy"
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/session/{sessionId}/update-aml-status/": {
      "patch": {
        "summary": "Perbarui status pemeriksaan AML",
        "description": "Tetapkan status pemeriksaan Skrining AML sesi secara keseluruhan (`status` dari entri `aml_screenings[]` dalam keputusan sesi), misalnya `Approved` setelah tim Anda menyelesaikan setiap hit. Berfungsi untuk ID sesi KYC dan KYB; teruskan `node_id` (parameter kueri atau kolom body) jika sesi menjalankan lebih dari satu langkah AML, jika tidak pemeriksaan AML terbaru yang akan diperbarui. Saat status benar-benar berubah, entri aktivitas `AML_STATUS_UPDATED` dicatat dan [webhook](https://docs.didit.me/id/integration/webhooks) `data.updated` dikirim; mengirimkan status saat ini mengembalikan `200` dan tidak mengubah apa pun. Status sesi tidak dihitung ulang: gunakan `PATCH /v3/session/{sessionId}/update-status/` untuk keputusan sesi dan `PATCH /v3/session/{sessionId}/update-aml-hit-status/` untuk hit tunggal. Kunci API dengan cakupan memerlukan `decisions: write`.",
        "operationId": "patch_v3_session_update_aml_status",
        "x-didit-sdk": {
          "resource": "sessions",
          "method": "update_aml_status",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Sessions"
        ],
        "parameters": [
          {
            "name": "sessionId",
            "in": "path",
            "required": true,
            "description": "UUID sesi verifikasi (`session_id` yang dikembalikan oleh `POST /v3/session/`). Menerima ID sesi Verifikasi Pengguna (KYC) dan Verifikasi Bisnis (KYB): server mencari ID tersebut di kedua jenis sesi. Harus berupa UUID dengan format yang benar; nilai yang salah format tidak cocok dengan rute dan mengembalikan HTML `404`.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "11111111-2222-3333-4444-555555555555"
            }
          },
          {
            "name": "node_id",
            "in": "query",
            "required": false,
            "description": "ID node graf alur kerja dari pemeriksaan AML yang akan diperbarui. Hanya diperlukan jika sesi menjalankan lebih dari satu langkah AML. Memiliki prioritas lebih tinggi daripada `node_id` di dalam badan permintaan.",
            "schema": {
              "type": "string",
              "example": "feature_aml_1"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "status"
                ],
                "properties": {
                  "status": {
                    "type": "string",
                    "enum": [
                      "Not Finished",
                      "Approved",
                      "Declined",
                      "In Review",
                      "Resub Requested"
                    ],
                    "description": "Status baru dari pemeriksaan AML.",
                    "example": "Approved"
                  },
                  "node_id": {
                    "type": "string",
                    "description": "ID node graf alur kerja dari pemeriksaan AML, sebagai alternatif untuk parameter kueri.",
                    "example": "feature_aml_1"
                  }
                }
              },
              "example": {
                "status": "Approved"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X PATCH 'https://verification.didit.me/v3/session/11111111-2222-3333-4444-555555555555/update-aml-status/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"status\": \"Approved\"}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.update_aml_status(\n    \"11111111-2222-3333-4444-555555555555\",\n    status=\"Approved\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.updateAmlStatus(\"11111111-2222-3333-4444-555555555555\", {\n  status: \"Approved\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.UpdateAMLStatus(ctx, \"11111111-2222-3333-4444-555555555555\", didit.SessionsUpdateAMLStatusParams{\n\tStatus: \"Approved\",\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.SessionsUpdateAmlStatusParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().updateAmlStatus(\"11111111-2222-3333-4444-555555555555\", SessionsUpdateAmlStatusParams.builder()\n        .status(SessionsUpdateAmlStatusParams.Status.of(\"Approved\"))\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->sessions->updateAmlStatus('11111111-2222-3333-4444-555555555555', [\n    'status' => 'Approved',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.update_aml_status(\n  \"11111111-2222-3333-4444-555555555555\",\n  status: \"Approved\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.UpdateAmlStatusAsync(\"11111111-2222-3333-4444-555555555555\", new SessionsUpdateAmlStatusParams\n{\n    Status = \"Approved\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "Status pemeriksaan AML ditetapkan (atau tidak berubah jika sudah memiliki nilai ini).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "message",
                    "status",
                    "previous_status"
                  ],
                  "properties": {
                    "message": {
                      "type": "string",
                      "description": "Selalu `AML status updated successfully`."
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "Not Finished",
                        "Approved",
                        "Declined",
                        "In Review",
                        "Resub Requested"
                      ],
                      "description": "Status pemeriksaan AML saat ini."
                    },
                    "previous_status": {
                      "type": "string",
                      "enum": [
                        "Not Finished",
                        "Approved",
                        "Declined",
                        "In Review",
                        "Resub Requested"
                      ],
                      "description": "Status sebelum pemanggilan. Sama dengan `status` jika tidak ada yang berubah."
                    }
                  }
                },
                "example": {
                  "message": "AML status updated successfully",
                  "status": "Approved",
                  "previous_status": "In Review"
                }
              }
            }
          },
          "400": {
            "description": "Kesalahan validasi: `status` tidak ada atau bukan salah satu dari nilai yang diizinkan. Pencarian pemeriksaan AML dijalankan terlebih dahulu, sehingga sesi tanpa pemeriksaan AML mengembalikan `404` bahkan dengan isi permintaan yang tidak valid.",
            "content": {
              "application/json": {
                "examples": {
                  "Missing status": {
                    "summary": "Isi kosong atau tanpa status",
                    "value": {
                      "status": [
                        "This field is required."
                      ]
                    }
                  },
                  "Invalid status": {
                    "summary": "status tidak ada di dalam enum",
                    "value": {
                      "status": [
                        "\"Cleared\" is not a valid choice."
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Kunci API dengan cakupan terbatas telah kedaluwarsa. Ini satu-satunya kasus yang mengembalikan `401`: kunci yang hilang, tidak valid, atau dicabut mengembalikan `403`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "Pesan kesalahan yang mudah dibaca manusia."
                    }
                  }
                },
                "examples": {
                  "Expired key": {
                    "summary": "Tanggal kedaluwarsa kunci telah lewat",
                    "value": {
                      "detail": "This API key has expired."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Kegagalan autentikasi atau otorisasi. Kunci yang hilang mengembalikan `403`, begitu juga dengan kunci dari aplikasi lain, kunci dengan cakupan tanpa izin yang dibutuhkan endpoint ini, dan permintaan dari luar daftar izin IP kunci tersebut; kunci yang salah, dicabut, atau kedaluwarsa mengembalikan `401`. Bedakan kegagalan tersebut berdasarkan `detail`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "Pesan kesalahan yang mudah dibaca manusia."
                    }
                  }
                },
                "examples": {
                  "Missing or invalid credentials": {
                    "summary": "Tidak ada header x-api-key, atau kunci gagal divalidasi",
                    "value": {
                      "detail": "Authentication credentials were not provided or are invalid."
                    }
                  },
                  "Other application": {
                    "summary": "Kunci valid milik aplikasi yang berbeda dari sesi",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Scoped key without decisions write": {
                    "summary": "Kunci ber-scope tidak memiliki decisions: write",
                    "value": {
                      "detail": "This API key has no write access to decisions."
                    }
                  },
                  "IP not allowed": {
                    "summary": "Permintaan dari luar daftar izin IP kunci",
                    "value": {
                      "detail": "This API key can't be used from this IP address."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Sesi tidak ada, telah dihapus, atau berada di luar batas kunci dengan cakupan terbatas, atau tidak memiliki pemeriksaan AML (untuk `node_id` yang diberikan). Pencarian sesi berjalan sebelum pemeriksaan kredensial, sehingga `sessionId` yang tidak dikenal mengembalikan `404` bahkan tanpa kunci yang valid.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "Pesan kesalahan yang mudah dibaca manusia."
                    }
                  }
                },
                "examples": {
                  "Unknown session": {
                    "summary": "Tidak ada sesi dengan ID ini, atau telah dihapus",
                    "value": {
                      "detail": "Not found."
                    }
                  },
                  "Outside key limits": {
                    "summary": "Sesi berada di luar batas kunci dengan cakupan terbatas (juga dikembalikan untuk sesi yang baru saja dihapus)",
                    "value": {
                      "detail": "Session not found."
                    }
                  },
                  "No AML check": {
                    "summary": "Sesi tidak pernah menjalankan langkah AML",
                    "value": {
                      "detail": "The session does not have an AML check."
                    }
                  },
                  "No AML check for node": {
                    "summary": "node_id tidak cocok dengan pemeriksaan AML pada sesi tersebut",
                    "value": {
                      "detail": "The session does not have an AML check for node 'feature_aml_2'."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Batas laju terlampaui: 300 permintaan penulisan (POST, PATCH, DELETE) per menit per kunci API. Tunggu selama `Retry-After` detik sebelum mencoba lagi; header `X-RateLimit-*` menunjukkan anggaran tersebut.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "Pesan kesalahan yang mudah dibaca manusia."
                    }
                  }
                },
                "examples": {
                  "Rate limited": {
                    "summary": "Anggaran untuk menit saat ini habis",
                    "value": {
                      "detail": "Write request rate limit exceeded. You can make up to 300 requests per minute."
                    }
                  }
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Detik untuk menunggu sebelum mencoba lagi.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "example": 30
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/status/": {
      "get": {
        "summary": "Dapatkan status layanan (publik, tanpa autentikasi)",
        "description": "Mengembalikan status setiap layanan Didit (`operational`, `degraded`, atau `down`), status keseluruhan (kondisi terburuk di antaranya), dan insiden yang sedang berlangsung atau diselesaikan dalam 7 hari terakhir. Gunakan ini untuk mendukung widget status atau memeriksa status Didit dari integrasi Anda.\n\nPublik: jangan kirimkan header autentikasi. Respons tidak berisi data organisasi dan sama untuk setiap pemanggil. Respons di-cache selama 30 detik, jadi lakukan polling tidak lebih dari sekali setiap 30 detik.",
        "operationId": "get_v3_status",
        "tags": [
          "Status"
        ],
        "security": [
          {}
        ],
        "parameters": [],
        "responses": {
          "200": {
            "description": "Status layanan saat ini.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ServiceStatusFeed"
                },
                "examples": {
                  "One service degraded": {
                    "summary": "Insiden yang sedang berlangsung dan satu insiden yang diselesaikan minggu ini",
                    "value": {
                      "status": "degraded",
                      "updated_at": "2026-10-13T09:41:07.512345Z",
                      "services": [
                        {
                          "key": "service_id_verification",
                          "name": "ID verification",
                          "status": "operational"
                        },
                        {
                          "key": "service_liveness_face_match",
                          "name": "Liveness and face match",
                          "status": "operational"
                        },
                        {
                          "key": "service_aml_screening",
                          "name": "AML screening",
                          "status": "operational"
                        },
                        {
                          "key": "service_kyb_registries",
                          "name": "KYB registries",
                          "status": "operational"
                        },
                        {
                          "key": "service_database_validation",
                          "name": "Database validation",
                          "status": "degraded"
                        },
                        {
                          "key": "service_phone_delivery",
                          "name": "Phone verification delivery",
                          "status": "operational"
                        },
                        {
                          "key": "service_email_delivery",
                          "name": "Email verification delivery",
                          "status": "operational"
                        },
                        {
                          "key": "service_transaction_monitoring",
                          "name": "Transaction monitoring",
                          "status": "operational"
                        }
                      ],
                      "incidents": [
                        {
                          "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                          "service": "service_database_validation",
                          "service_name": "Database validation",
                          "state": "degraded",
                          "status": "ongoing",
                          "title": "Database validation is degraded in Brazil.",
                          "body": "Checks against Brazil (CPF) may be slow or fail since 08:55 UTC.",
                          "affected": "Brazil (CPF)",
                          "country_name": "Brazil",
                          "started_at": "2026-10-13T08:55:00Z",
                          "resolved_at": null,
                          "duration_minutes": null
                        },
                        {
                          "id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
                          "service": "service_aml_screening",
                          "service_name": "AML screening",
                          "state": "down",
                          "status": "resolved",
                          "title": "AML screening is back to normal.",
                          "body": "Recovered at 14:32 UTC after 17 minutes.",
                          "affected": "",
                          "country_name": "",
                          "started_at": "2026-10-11T14:15:00Z",
                          "resolved_at": "2026-10-11T14:32:00Z",
                          "duration_minutes": 17
                        }
                      ]
                    }
                  },
                  "All operational": {
                    "summary": "Tidak ada insiden dalam 7 hari terakhir",
                    "value": {
                      "status": "operational",
                      "updated_at": "2026-10-13T09:41:07.512345Z",
                      "services": [
                        {
                          "key": "service_id_verification",
                          "name": "ID verification",
                          "status": "operational"
                        },
                        {
                          "key": "service_liveness_face_match",
                          "name": "Liveness and face match",
                          "status": "operational"
                        },
                        {
                          "key": "service_aml_screening",
                          "name": "AML screening",
                          "status": "operational"
                        },
                        {
                          "key": "service_kyb_registries",
                          "name": "KYB registries",
                          "status": "operational"
                        },
                        {
                          "key": "service_database_validation",
                          "name": "Database validation",
                          "status": "operational"
                        },
                        {
                          "key": "service_phone_delivery",
                          "name": "Phone verification delivery",
                          "status": "operational"
                        },
                        {
                          "key": "service_email_delivery",
                          "name": "Email verification delivery",
                          "status": "operational"
                        },
                        {
                          "key": "service_transaction_monitoring",
                          "name": "Transaction monitoring",
                          "status": "operational"
                        }
                      ],
                      "incidents": []
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Lebih dari 600 permintaan GET dalam satu menit dari alamat IP yang sama (atau kunci API yang sama, jika Anda mengirimkannya). Patuhi `Retry-After` sebelum mencoba lagi.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "detail"
                  ],
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "detail": "GET request rate limit exceeded. You can make up to 600 requests per minute."
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -fsS https://verification.didit.me/v3/status/"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "import requests\n\nresp = requests.get('https://verification.didit.me/v3/status/', timeout=5)\nresp.raise_for_status()\nfeed = resp.json()\nprint(feed['status'])\nfor service in feed['services']:\n    if service['status'] != 'operational':\n        print(service['key'], service['status'])"
          },
          {
            "lang": "javascript",
            "label": "JavaScript",
            "source": "const feed = await fetch('https://verification.didit.me/v3/status/').then((r) => r.json());\nconsole.log(feed.status);\nconst affected = feed.services.filter((s) => s.status !== 'operational');\nconsole.log(affected.map((s) => `${s.key}: ${s.status}`));"
          }
        ],
        "x-didit-sdk": {
          "resource": "system",
          "method": "retrieve_status",
          "auth": "public",
          "server": false
        }
      }
    },
    "/v3/organization/bank-verification-pricing/": {
      "get": {
        "summary": "Dapatkan harga verifikasi bank (publik, tanpa autentikasi)",
        "description": "Mengembalikan harga daftar dari setiap metode Bank Verification di setiap negara: proses masuk bank beserta add-on saldo dan transaksinya, serta pemeriksaan akun. Metode yang saat ini tidak ditawarkan oleh suatu negara ditampilkan sebagai tidak tersedia, tanpa harga. Gunakan ini untuk memperkirakan biaya langkah bank sebelum Anda menyusun alur kerja, atau untuk menampilkan harga bank di produk Anda sendiri.\n\nPublik: jangan kirimkan header autentikasi. Respons tidak berisi data organisasi dan sama untuk setiap pemanggil. Respons di-cache secara publik selama satu jam dan menyertakan `ETag`, jadi kirimkan `If-None-Match` untuk mendapatkan `304 Not Modified` saat tidak ada perubahan.\n\nSuatu metode bernilai `available` hanya jika Didit menyediakannya di lingkungan produksi saat ini, dan `price_usd`-nya bernilai `null` di tempat lain, sehingga feed tidak pernah menampilkan harga yang tidak dapat Anda beli. `available: false` mencakup negara tanpa harga yang disetujui, metode yang tidak didukung oleh negara tersebut, dan rute yang belum diaktifkan.\n\nIni adalah harga daftar sebelum diskon paket Anda. Diskon paket Anda berlaku untuk seluruh harga bank, dan harga hasil negosiasi atau kontrak menggantikan harga daftar untuk organisasi Anda.",
        "operationId": "get_v3_bank_verification_pricing",
        "tags": [
          "Pricing"
        ],
        "security": [
          {}
        ],
        "parameters": [],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -fsS https://verification.didit.me/v3/organization/bank-verification-pricing/"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# This call needs no API key.\nclient = Didit()\n\nresult = client.pricing.bank_verification()\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// This call needs no API key.\nconst didit = new Didit();\n\nconst result = await didit.pricing.bankVerification();\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// This call needs no API key.\nclient := didit.NewClient()\n\nresult, err := client.Pricing.BankVerification(ctx)\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// This call needs no API key.\nDidit client = new Didit();\n\nvar result = client.pricing().bankVerification();\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// This call needs no API key.\n$didit = new DiditClient();\n\n$result = $didit->pricing->bankVerification();\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# This call needs no API key.\ndidit = Didit::Client.new\n\nresult = didit.pricing.bank_verification\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// This call needs no API key.\nusing var client = new DiditClient();\n\nvar result = await client.Pricing.BankVerificationAsync();\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "x-didit-sdk": {
          "resource": "pricing",
          "method": "bank_verification",
          "auth": "none",
          "server": true
        },
        "responses": {
          "200": {
            "description": "Daftar harga Verifikasi Bank berdasarkan negara.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BankVerificationPricing"
                },
                "examples": {
                  "Two countries": {
                    "summary": "Satu negara dengan kedua metode, satu tanpa keduanya",
                    "value": {
                      "currency": "USD",
                      "statement_upload": {
                        "price_usd": "0.0000",
                        "included_after_charged_bank_attempt": true,
                        "standalone_available": false
                      },
                      "own_provider_fee_usd": "0.0200",
                      "countries": {
                        "GBR": {
                          "name": "United Kingdom",
                          "methods": {
                            "open_banking": {
                              "available": true,
                              "market": "UK and EEA",
                              "price_usd": "0.7900",
                              "add_ons": {
                                "balance": "0.3500",
                                "transactions": "1.3000"
                              }
                            },
                            "account_lookup": {
                              "available": true,
                              "price_usd": "0.4000"
                            }
                          }
                        },
                        "CAN": {
                          "name": "Canada",
                          "methods": {
                            "open_banking": {
                              "available": false,
                              "market": null,
                              "price_usd": null,
                              "add_ons": {}
                            },
                            "account_lookup": {
                              "available": false,
                              "price_usd": null
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "304": {
            "description": "Tidak dimodifikasi: `ETag` yang Anda kirim di `If-None-Match` masih cocok. Tidak ada isi."
          }
        }
      }
    },
    "/v3/session/{sessionId}/simulate/": {
      "post": {
        "summary": "Simulasikan status sesi sandbox",
        "description": "Paksa status terminal pada sesi sandbox setelah proses selesai, dari backend Anda, tanpa menjalankan alur. Khusus aplikasi sandbox: sesi produksi mengembalikan `404`. Berfungsi untuk sesi Verifikasi Pengguna (KYC) dan Verifikasi Bisnis (KYB).\n\nTetapkan `new_status`, atau biarkan `scenario` atau `risk` menyediakannya. `risk` (atau risiko pertama yang dibawa oleh nilai khusus skenario) menambahkan peringatan tersebut ke sesi. Perubahan ini dicatat dalam aktivitas sesi.\n\n`send_webhooks` (default `true`) mengirimkan webhook yang persis sama dengan yang dikirimkan oleh perubahan status nyata. Dengan `false`, status tetap berubah dan konsol tetap diperbarui secara langsung, tetapi tidak ada webhook yang dicatat atau dikirim, pemulihan webhook yang terlewat tidak pernah mengirim ulang keputusan tersebut, dan perubahan status berikutnya mengirimkan webhook seperti biasa. Respons menampilkan kembali nilai yang diterapkan.\n\nMemerlukan hak istimewa `write:sessions`; kunci API dengan cakupan tertentu memerlukan akses tulis ke sesi. `session_id` yang tidak dikenal mengembalikan `404` dan sesi aplikasi lain mengembalikan `403`, keduanya sebelum isi permintaan dibaca; sesi produksi mengembalikan `404` hanya setelah isi permintaan divalidasi. Untuk melakukan simulasi dari alur yang di-hosting dengan token sesi itu sendiri, gunakan `POST /v3/session/{sessionId}/sandbox/simulate/`. Lihat [Sandbox & Test Data](/id/integration/sandbox-testing) untuk katalog skenario.",
        "operationId": "post_v3_session_simulate",
        "tags": [
          "Sessions"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "in": "path",
            "name": "sessionId",
            "required": true,
            "description": "UUID sesi verifikasi sandbox. Menerima ID sesi pengguna (KYC) dan bisnis (KYB).",
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SandboxSimulateRequest"
              },
              "examples": {
                "Scenario Without Webhooks": {
                  "summary": "Tolak melalui skenario tanpa mengirim webhook",
                  "value": {
                    "scenario": "decline_aml_hit",
                    "send_webhooks": false
                  }
                },
                "Status Only": {
                  "summary": "Setujui dan kirim webhook seperti biasa",
                  "value": {
                    "new_status": "Approved"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Status berubah.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SandboxSimulateResponse"
                },
                "examples": {
                  "Simulated": {
                    "summary": "Ditolak melalui skenario, webhook tidak dikirim",
                    "value": {
                      "session_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "previous_status": "In Progress",
                      "status": "Declined",
                      "scenario": "decline_aml_hit",
                      "risk": "POSSIBLE_MATCH_FOUND",
                      "send_webhooks": false
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Kesalahan validasi: skenario atau risiko yang tidak diketahui, tidak ada `new_status` saat `scenario` maupun `risk` tidak menyediakannya, status yang tidak diatur oleh endpoint ini, atau sesi sudah memiliki status yang diminta (array JSON mentah).",
            "content": {
              "application/json": {
                "examples": {
                  "Unknown Scenario": {
                    "summary": "skenario tidak ada di dalam katalog",
                    "value": {
                      "scenario": [
                        "Unknown sandbox scenario: 'not-a-scenario'."
                      ]
                    }
                  },
                  "Unknown Risk": {
                    "summary": "risk tidak ada di dalam katalog",
                    "value": {
                      "risk": [
                        "Unknown sandbox risk case: 'NOT_A_RISK'."
                      ]
                    }
                  },
                  "Missing new_status": {
                    "summary": "Tidak ada new_status, skenario, atau risiko",
                    "value": {
                      "new_status": [
                        "This field is required."
                      ]
                    }
                  },
                  "Invalid new_status": {
                    "summary": "Status yang tidak ditetapkan oleh simulasi",
                    "value": {
                      "new_status": [
                        "\"Resubmitted\" is not a valid choice."
                      ]
                    }
                  },
                  "Same Status": {
                    "summary": "Sesi sudah memiliki status ini",
                    "value": [
                      "The new status is the same as the current status."
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Kunci API dengan cakupan terbatas telah kedaluwarsa.",
            "content": {
              "application/json": {
                "examples": {
                  "Expired API Key": {
                    "summary": "Kunci API ber-scope melewati tanggal kedaluwarsanya",
                    "value": {
                      "detail": "This API key has expired."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Kredensial tidak ada, pemanggil tanpa hak istimewa `write:sessions`, kunci API dengan pembatasan cakupan tanpa akses yang dibutuhkan endpoint ini, atau `session_id` milik aplikasi lain.",
            "content": {
              "application/json": {
                "examples": {
                  "Invalid Credentials": {
                    "summary": "x-api-key tidak ada atau tidak valid",
                    "value": {
                      "detail": "Authentication credentials were not provided or are invalid."
                    }
                  },
                  "Missing Privilege": {
                    "summary": "Pemanggil tidak memiliki izin write:sessions",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Scoped Key Without Access": {
                    "summary": "Kunci API ber-scope tanpa akses ini",
                    "value": {
                      "detail": "This API key has no write access to sessions."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Tidak ada sesi dengan `session_id` ini, atau ini adalah sesi produksi (non-sandbox).",
            "content": {
              "application/json": {
                "examples": {
                  "Not Found": {
                    "summary": "Sesi tidak dikenal atau sesi produksi",
                    "value": {
                      "detail": "Not found."
                    }
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST \\\n  https://verification.didit.me/v3/session/3fa85f64-5717-4562-b3fc-2c963f66afa6/simulate/ \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"scenario\": \"decline_aml_hit\", \"send_webhooks\": false}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.simulate(\n    \"3fa85f64-5717-4562-b3fc-2c963f66afa6\",\n    scenario=\"decline_aml_hit\",\n    send_webhooks=False,\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.simulate(\"3fa85f64-5717-4562-b3fc-2c963f66afa6\", {\n  scenario: \"decline_aml_hit\",\n  send_webhooks: false,\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.Simulate(ctx, \"3fa85f64-5717-4562-b3fc-2c963f66afa6\", didit.SandboxSimulateRequest{\n\tScenario:     didit.String(\"decline_aml_hit\"),\n\tSendWebhooks: didit.Bool(false),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.SandboxSimulateRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().simulate(\"3fa85f64-5717-4562-b3fc-2c963f66afa6\", SandboxSimulateRequest.builder()\n        .scenario(\"decline_aml_hit\")\n        .sendWebhooks(false)\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->sessions->simulate('3fa85f64-5717-4562-b3fc-2c963f66afa6', [\n    'scenario' => 'decline_aml_hit',\n    'send_webhooks' => false,\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.simulate(\n  \"3fa85f64-5717-4562-b3fc-2c963f66afa6\",\n  scenario: \"decline_aml_hit\",\n  send_webhooks: false\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.SimulateAsync(\"3fa85f64-5717-4562-b3fc-2c963f66afa6\", new SandboxSimulateRequest\n{\n    Scenario = \"decline_aml_hit\",\n    SendWebhooks = false,\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "x-didit-sdk": {
          "resource": "sessions",
          "method": "simulate",
          "auth": "api_key",
          "server": true
        }
      }
    },
    "/v3/session/{sessionId}/sandbox/simulate/": {
      "post": {
        "summary": "Simulasikan status sesi sandbox dari klien",
        "description": "Simulasi yang sama seperti `POST /v3/session/{sessionId}/simulate/`, diautentikasi dengan `Session-Token` milik sesi itu sendiri (dikembalikan di `session_token` oleh [Create Session](/id/sessions-api/create-session)) alih-alih kunci API Anda, sehingga harness pengujian atau alur yang di-hosting dapat memanggilnya dari klien. Isi permintaan, respons, dan `send_webhooks` berperilaku persis seperti pada endpoint tersebut.\n\n`Session-Token` dari aplikasi produksi (non-sandbox), atau yang tidak cocok dengan `sessionId` di jalur, mengembalikan `404`. Lihat [Sandbox & Data Pengujian](/id/integration/sandbox-testing).",
        "operationId": "post_v3_session_sandbox_simulate",
        "tags": [
          "Sessions"
        ],
        "security": [
          {
            "SessionTokenAuth": []
          }
        ],
        "parameters": [
          {
            "in": "path",
            "name": "sessionId",
            "required": true,
            "description": "UUID sesi verifikasi sandbox. Harus cocok dengan sesi yang dienkode dalam Session-Token yang digunakan untuk mengautentikasi.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SandboxSimulateRequest"
              },
              "examples": {
                "Scenario Without Webhooks": {
                  "summary": "Tolak melalui skenario tanpa mengirim webhook",
                  "value": {
                    "scenario": "decline_aml_hit",
                    "send_webhooks": false
                  }
                },
                "Status Only": {
                  "summary": "Setujui dan kirim webhook seperti biasa",
                  "value": {
                    "new_status": "Approved"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Status berubah.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SandboxSimulateResponse"
                },
                "examples": {
                  "Simulated": {
                    "summary": "Ditolak melalui skenario, webhook tidak dikirim",
                    "value": {
                      "session_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "previous_status": "In Progress",
                      "status": "Declined",
                      "scenario": "decline_aml_hit",
                      "risk": "POSSIBLE_MATCH_FOUND",
                      "send_webhooks": false
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Kesalahan validasi: skenario atau risiko yang tidak diketahui, tidak ada `new_status` saat `scenario` maupun `risk` tidak menyediakannya, status yang tidak diatur oleh endpoint ini, atau sesi sudah memiliki status yang diminta (array JSON mentah).",
            "content": {
              "application/json": {
                "examples": {
                  "Unknown Scenario": {
                    "summary": "skenario tidak ada di dalam katalog",
                    "value": {
                      "scenario": [
                        "Unknown sandbox scenario: 'not-a-scenario'."
                      ]
                    }
                  },
                  "Unknown Risk": {
                    "summary": "risk tidak ada di dalam katalog",
                    "value": {
                      "risk": [
                        "Unknown sandbox risk case: 'NOT_A_RISK'."
                      ]
                    }
                  },
                  "Missing new_status": {
                    "summary": "Tidak ada new_status, skenario, atau risiko",
                    "value": {
                      "new_status": [
                        "This field is required."
                      ]
                    }
                  },
                  "Invalid new_status": {
                    "summary": "Status yang tidak ditetapkan oleh simulasi",
                    "value": {
                      "new_status": [
                        "\"Resubmitted\" is not a valid choice."
                      ]
                    }
                  },
                  "Same Status": {
                    "summary": "Sesi sudah memiliki status ini",
                    "value": [
                      "The new status is the same as the current status."
                    ]
                  }
                }
              }
            }
          },
          "403": {
            "description": "Header `Session-Token` tidak ada atau tidak valid.",
            "content": {
              "application/json": {
                "examples": {
                  "Invalid Session Token": {
                    "summary": "Session-Token tidak ada atau tidak valid",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "`Session-Token` milik aplikasi produksi (non-sandbox), atau tidak cocok dengan `sessionId` di path.",
            "content": {
              "application/json": {
                "examples": {
                  "Not Found": {
                    "summary": "Sesi langsung, atau ketidakcocokan session_id / token",
                    "value": {
                      "detail": "Not found."
                    }
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST \\\n  https://verification.didit.me/v3/session/3fa85f64-5717-4562-b3fc-2c963f66afa6/sandbox/simulate/ \\\n  -H 'Session-Token: YOUR_SESSION_TOKEN' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"new_status\": \"Approved\", \"send_webhooks\": false}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "import requests\n\nresponse = requests.post(\n    \"https://verification.didit.me/v3/session/3fa85f64-5717-4562-b3fc-2c963f66afa6/sandbox/simulate/\",\n    headers={\"Session-Token\": \"YOUR_SESSION_TOKEN\"},\n    json={\"new_status\": \"Approved\", \"send_webhooks\": False},\n)\nresponse.raise_for_status()\nprint(response.json())"
          }
        ],
        "x-didit-sdk": {
          "resource": "sessions",
          "method": "simulate_sandbox",
          "auth": "device_token",
          "server": false
        }
      }
    },
    "/v3/session/{sessionId}/features/overrides/": {
      "get": {
        "summary": "Daftar penimpaan pemeriksaan sesi",
        "description": "Setiap penggantian status fitur (langkah) individu pada sesi Verifikasi Pengguna (KYC) atau Verifikasi Bisnis (KYB), yang terbaru terlebih dahulu dan tidak dipaginasi: yang diterapkan, yang menunggu orang tersebut menyelesaikan alur (`pending_until_flow_finishes`), dan yang dibatalkan, masing-masing memuat pihak yang meminta, alasannya, dan apakah itu diterapkan saat orang tersebut masih berada di dalam alur (`forced`).\n\n`person_in_flow` memberi tahu Anda apakah penggantian baru dengan `defer_until_flow_finishes: true` akan menunggu. `flow_finished_at` adalah waktu saat orang tersebut terakhir kali menyelesaikan alur; bernilai `null` selama mereka masih berada di dalamnya (termasuk pengiriman ulang) dan ketika sesi ditutup sebelum mereka selesai.\n\nMemerlukan hak istimewa `read:sessions`; kunci API dengan cakupan terbatas memerlukan akses baca ke keputusan.",
        "operationId": "get_v3_session_feature_overrides",
        "tags": [
          "Sessions"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "in": "path",
            "name": "sessionId",
            "required": true,
            "description": "UUID sesi verifikasi. Menerima ID sesi pengguna (KYC) dan bisnis (KYB).",
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Penimpaan pemeriksaan sesi, yang terbaru terlebih dahulu.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "session_id",
                    "person_in_flow",
                    "flow_finished_at",
                    "overrides"
                  ],
                  "properties": {
                    "session_id": {
                      "type": "string",
                      "format": "uuid",
                      "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
                    },
                    "person_in_flow": {
                      "type": "boolean",
                      "description": "Apakah orang tersebut masih berada di dalam alur, sehingga override baru dengan `defer_until_flow_finishes: true` akan menunggu.",
                      "example": true
                    },
                    "flow_finished_at": {
                      "type": "string",
                      "format": "date-time",
                      "nullable": true,
                      "description": "Waktu pengguna terakhir menyelesaikan alur. `null` selama mereka masih berada di dalamnya (termasuk pengiriman ulang) dan saat sesi ditutup sebelum mereka selesai (ditinggalkan, kedaluwarsa, atau diputuskan di tengah alur).",
                      "example": null
                    },
                    "overrides": {
                      "type": "array",
                      "description": "Setiap penggantian pada sesi, yang terbaru terlebih dahulu.",
                      "items": {
                        "$ref": "#/components/schemas/FeatureStatusOverride"
                      }
                    }
                  }
                },
                "examples": {
                  "Overrides": {
                    "summary": "Satu penimpaan menunggu, satu diterapkan",
                    "value": {
                      "session_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "person_in_flow": true,
                      "flow_finished_at": null,
                      "overrides": [
                        {
                          "id": "9b2f4c1e-8d3a-4e5f-a6b7-c8d9e0f1a2b3",
                          "node_id": "feature_liveness_1",
                          "feature_type": "",
                          "feature_model": "Face",
                          "previous_status": "Declined",
                          "new_status": "Approved",
                          "state": "pending_until_flow_finishes",
                          "forced": false,
                          "reason": "Liveness retried with a reviewer present.",
                          "requested_by": {
                            "email": "reviewer@example.com",
                            "name": "Alex Reviewer",
                            "type": "CONSOLE_USER"
                          },
                          "requested_at": "2026-10-13T09:15:00Z",
                          "applied_at": null,
                          "cancelled_at": null,
                          "cancel_reason": null
                        },
                        {
                          "id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
                          "node_id": "feature_ocr_1",
                          "feature_type": "",
                          "feature_model": "KYC",
                          "previous_status": "In Review",
                          "new_status": "Approved",
                          "state": "applied",
                          "forced": true,
                          "reason": "Document manually verified by compliance.",
                          "requested_by": {
                            "email": "reviewer@example.com",
                            "name": "Alex Reviewer",
                            "type": "CONSOLE_USER"
                          },
                          "requested_at": "2026-10-13T09:15:00Z",
                          "applied_at": "2026-10-13T09:15:00Z",
                          "cancelled_at": null,
                          "cancel_reason": null
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Kunci API dengan cakupan terbatas telah kedaluwarsa.",
            "content": {
              "application/json": {
                "examples": {
                  "Expired API Key": {
                    "summary": "Kunci API ber-scope melewati tanggal kedaluwarsanya",
                    "value": {
                      "detail": "This API key has expired."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Kredensial tidak ada, pemanggil tanpa hak istimewa `read:sessions`, kunci API dengan pembatasan cakupan tanpa akses yang dibutuhkan endpoint ini, atau `session_id` milik aplikasi lain.",
            "content": {
              "application/json": {
                "examples": {
                  "Invalid Credentials": {
                    "summary": "x-api-key tidak ada atau tidak valid",
                    "value": {
                      "detail": "Authentication credentials were not provided or are invalid."
                    }
                  },
                  "Missing Privilege": {
                    "summary": "Pemanggil tidak memiliki izin read:sessions",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Scoped Key Without Access": {
                    "summary": "Kunci API ber-scope tanpa akses ini",
                    "value": {
                      "detail": "This API key has no read access to decisions."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Tidak ada sesi KYC atau KYB dengan `session_id` ini.",
            "content": {
              "application/json": {
                "examples": {
                  "Not Found": {
                    "summary": "session_id tidak dikenal",
                    "value": {
                      "detail": "Not found."
                    }
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET \\\n  https://verification.didit.me/v3/session/3fa85f64-5717-4562-b3fc-2c963f66afa6/features/overrides/ \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.list_feature_overrides(\n    \"3fa85f64-5717-4562-b3fc-2c963f66afa6\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.listFeatureOverrides(\"3fa85f64-5717-4562-b3fc-2c963f66afa6\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.ListFeatureOverrides(ctx, \"3fa85f64-5717-4562-b3fc-2c963f66afa6\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().listFeatureOverrides(\"3fa85f64-5717-4562-b3fc-2c963f66afa6\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->sessions->listFeatureOverrides('3fa85f64-5717-4562-b3fc-2c963f66afa6');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.list_feature_overrides(\"3fa85f64-5717-4562-b3fc-2c963f66afa6\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.ListFeatureOverridesAsync(\"3fa85f64-5717-4562-b3fc-2c963f66afa6\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "x-didit-sdk": {
          "resource": "sessions",
          "method": "list_feature_overrides",
          "auth": "api_key",
          "server": true
        }
      }
    },
    "/v3/session/{sessionId}/features/overrides/{overrideId}/cancel/": {
      "post": {
        "summary": "Batalkan override pemeriksaan yang menunggu alur selesai",
        "description": "Batalkan override status fitur (langkah) yang masih `pending_until_flow_finishes`, sehingga tidak pernah diterapkan. Pemeriksaan mempertahankan statusnya, pembatalan dicatat dalam aktivitas sesi sebagai `FEATURE_OVERRIDE_CANCELLED`, dan tidak ada webhook yang dikirim. Responsnya adalah override dengan `state: cancelled` dan `cancel_reason: cancelled_by_reviewer`.\n\nOverride yang sudah diterapkan atau dibatalkan mengembalikan `409` dengan kode `feature_override_not_pending`. Temukan ID override dengan `GET /v3/session/{sessionId}/features/overrides/` atau di dalam `override` yang dikembalikan oleh pembaruan status fitur.\n\nMemerlukan hak istimewa `write:sessions`; kunci API dengan cakupan memerlukan akses tulis ke keputusan.",
        "operationId": "post_v3_session_feature_override_cancel",
        "tags": [
          "Sessions"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "in": "path",
            "name": "sessionId",
            "required": true,
            "description": "UUID sesi verifikasi. Menerima ID sesi pengguna (KYC) dan bisnis (KYB).",
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
            }
          },
          {
            "in": "path",
            "name": "overrideId",
            "required": true,
            "description": "`id` dari override yang akan dibatalkan.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "9b2f4c1e-8d3a-4e5f-a6b7-c8d9e0f1a2b3"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Penggantian dibatalkan dan tidak akan pernah diterapkan.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FeatureStatusOverride"
                },
                "examples": {
                  "Cancelled": {
                    "summary": "Override yang dibatalkan",
                    "value": {
                      "id": "9b2f4c1e-8d3a-4e5f-a6b7-c8d9e0f1a2b3",
                      "node_id": "feature_liveness_1",
                      "feature_type": "",
                      "feature_model": "Face",
                      "previous_status": "Declined",
                      "new_status": "Approved",
                      "state": "cancelled",
                      "forced": false,
                      "reason": "Liveness retried with a reviewer present.",
                      "requested_by": {
                        "email": "reviewer@example.com",
                        "name": "Alex Reviewer",
                        "type": "CONSOLE_USER"
                      },
                      "requested_at": "2026-10-13T09:15:00Z",
                      "applied_at": null,
                      "cancelled_at": "2026-10-13T09:20:00Z",
                      "cancel_reason": "cancelled_by_reviewer"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Kunci API dengan cakupan terbatas telah kedaluwarsa.",
            "content": {
              "application/json": {
                "examples": {
                  "Expired API Key": {
                    "summary": "Kunci API ber-scope melewati tanggal kedaluwarsanya",
                    "value": {
                      "detail": "This API key has expired."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Kredensial tidak ada, pemanggil tanpa hak istimewa `write:sessions`, kunci API dengan pembatasan cakupan tanpa akses yang dibutuhkan endpoint ini, atau `session_id` milik aplikasi lain.",
            "content": {
              "application/json": {
                "examples": {
                  "Invalid Credentials": {
                    "summary": "x-api-key tidak ada atau tidak valid",
                    "value": {
                      "detail": "Authentication credentials were not provided or are invalid."
                    }
                  },
                  "Missing Privilege": {
                    "summary": "Pemanggil tidak memiliki izin write:sessions",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Scoped Key Without Access": {
                    "summary": "Kunci API ber-scope tanpa akses ini",
                    "value": {
                      "detail": "This API key has no write access to decisions."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Tidak ada sesi KYC atau KYB dengan `session_id` ini, atau sesi tidak memiliki override dengan `overrideId` ini.",
            "content": {
              "application/json": {
                "examples": {
                  "Not Found": {
                    "summary": "session_id tidak dikenal",
                    "value": {
                      "detail": "Not found."
                    }
                  },
                  "Override Not Found": {
                    "summary": "Tidak ada override dengan id ini pada sesi",
                    "value": {
                      "detail": "Override not found."
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "Penggantian telah diterapkan atau dibatalkan.",
            "content": {
              "application/json": {
                "examples": {
                  "Not Pending": {
                    "summary": "Hanya override yang sedang menunggu yang dapat dibatalkan",
                    "value": {
                      "detail": "This override is no longer pending: it already applied or was cancelled.",
                      "code": "feature_override_not_pending"
                    }
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST \\\n  https://verification.didit.me/v3/session/3fa85f64-5717-4562-b3fc-2c963f66afa6/features/overrides/9b2f4c1e-8d3a-4e5f-a6b7-c8d9e0f1a2b3/cancel/ \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.cancel_feature_override(\n    \"3fa85f64-5717-4562-b3fc-2c963f66afa6\",\n    \"9b2f4c1e-8d3a-4e5f-a6b7-c8d9e0f1a2b3\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.cancelFeatureOverride(\n  \"3fa85f64-5717-4562-b3fc-2c963f66afa6\",\n  \"9b2f4c1e-8d3a-4e5f-a6b7-c8d9e0f1a2b3\",\n);\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.CancelFeatureOverride(ctx, \"3fa85f64-5717-4562-b3fc-2c963f66afa6\", \"9b2f4c1e-8d3a-4e5f-a6b7-c8d9e0f1a2b3\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().cancelFeatureOverride(\"3fa85f64-5717-4562-b3fc-2c963f66afa6\", \"9b2f4c1e-8d3a-4e5f-a6b7-c8d9e0f1a2b3\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->sessions->cancelFeatureOverride('3fa85f64-5717-4562-b3fc-2c963f66afa6', '9b2f4c1e-8d3a-4e5f-a6b7-c8d9e0f1a2b3');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.cancel_feature_override(\n  \"3fa85f64-5717-4562-b3fc-2c963f66afa6\",\n  \"9b2f4c1e-8d3a-4e5f-a6b7-c8d9e0f1a2b3\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.CancelFeatureOverrideAsync(\"3fa85f64-5717-4562-b3fc-2c963f66afa6\", \"9b2f4c1e-8d3a-4e5f-a6b7-c8d9e0f1a2b3\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "x-didit-sdk": {
          "resource": "sessions",
          "method": "cancel_feature_override",
          "auth": "api_key",
          "server": true
        }
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/networks/{network_uuid}/tags/add/": {
      "post": {
        "summary": "Tambahkan tag ke jaringan",
        "description": "Menempatkan salah satu tag aplikasi Anda di jaringan. Mengembalikan detail jaringan, yang mana `tags` mencantumkan tag aplikasi Anda di jaringan tersebut, dengan `201` saat tag ditambahkan dan `200` saat tag sudah ada di jaringan. Tag milik aplikasi lain, atau yang tidak ada, mengembalikan 404 `Tag not found.`. Memerlukan kunci API akses penuh, atau `write:networks` untuk anggota konsol.",
        "operationId": "add_network_tag",
        "tags": [
          "Networks"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID organisasi."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID aplikasi."
          },
          {
            "name": "network_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
            },
            "description": "UUID jaringan."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/NetworkTagRequest"
              },
              "example": {
                "tag_uuid": "7c9e6679-7425-40de-944b-e07fc1f90ae7"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/networks/3fa85f64-5717-4562-b3fc-2c963f66afa6/tags/add/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"tag_uuid\": \"7c9e6679-7425-40de-944b-e07fc1f90ae7\"}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.networks.add_tag(\n    \"3fa85f64-5717-4562-b3fc-2c963f66afa6\",\n    tag_uuid=\"7c9e6679-7425-40de-944b-e07fc1f90ae7\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.networks.addTag(\"3fa85f64-5717-4562-b3fc-2c963f66afa6\", {\n  tag_uuid: \"7c9e6679-7425-40de-944b-e07fc1f90ae7\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Networks.AddTag(ctx, \"3fa85f64-5717-4562-b3fc-2c963f66afa6\", didit.NetworkTagRequest{\n\tTagUUID: \"7c9e6679-7425-40de-944b-e07fc1f90ae7\",\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.NetworkTagRequest;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.networks().addTag(\"3fa85f64-5717-4562-b3fc-2c963f66afa6\", NetworkTagRequest.builder()\n        .tagUuid(\"7c9e6679-7425-40de-944b-e07fc1f90ae7\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->networks->addTag('3fa85f64-5717-4562-b3fc-2c963f66afa6', [\n    'tag_uuid' => '7c9e6679-7425-40de-944b-e07fc1f90ae7',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.networks.add_tag(\n  \"3fa85f64-5717-4562-b3fc-2c963f66afa6\",\n  tag_uuid: \"7c9e6679-7425-40de-944b-e07fc1f90ae7\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Networks.AddTagAsync(\"3fa85f64-5717-4562-b3fc-2c963f66afa6\", new NetworkTagRequest\n{\n    TagUuid = \"7c9e6679-7425-40de-944b-e07fc1f90ae7\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "201": {
            "description": "Tag telah ditambahkan. Mengembalikan detail jaringan.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NetworkDetailResponse"
                },
                "example": {
                  "uuid": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                  "network_id": "N-0042",
                  "name": null,
                  "status": "in_review",
                  "risk": {
                    "score": 82,
                    "band": "high",
                    "bar": 0.82
                  },
                  "pattern_types": [
                    "exact_same_device",
                    "same_email"
                  ],
                  "signal_types": [
                    "device",
                    "email"
                  ],
                  "member_counts": {
                    "total": 3,
                    "users": 3,
                    "businesses": 0,
                    "transaction_parties": 0
                  },
                  "member_status": {
                    "approved": 1,
                    "declined": 1,
                    "in_review": 0,
                    "not_completed": 1
                  },
                  "signal_coverage": {
                    "device": {
                      "signals": 1,
                      "subjects": 3,
                      "coverage": 1.0
                    },
                    "email": {
                      "signals": 1,
                      "subjects": 2,
                      "coverage": 0.6667
                    }
                  },
                  "first_activity_at": "2026-10-01T09:12:44Z",
                  "last_activity_at": "2026-10-12T16:03:10Z",
                  "stats": {
                    "members": {
                      "total": 3,
                      "users": 3,
                      "businesses": 0,
                      "transaction_parties": 0
                    },
                    "member_status": {
                      "approved": 1,
                      "declined": 1,
                      "in_review": 0,
                      "not_completed": 1
                    },
                    "signals": {
                      "total": 2,
                      "by_type": {
                        "device": {
                          "signals": 1,
                          "subjects": 3,
                          "coverage": 1.0
                        },
                        "email": {
                          "signals": 1,
                          "subjects": 2,
                          "coverage": 0.6667
                        }
                      }
                    }
                  },
                  "fraud_tags": [],
                  "risk_signals": {
                    "residential_proxy_reuse": {
                      "detected": false,
                      "signal_count": 0,
                      "max_subject_count": 0
                    },
                    "email_intelligence": {
                      "enriched_signal_count": 1,
                      "high_risk_count": 0,
                      "social_profile_count": 0
                    },
                    "phone_intelligence": {
                      "enriched_signal_count": 0,
                      "high_risk_count": 0
                    }
                  },
                  "reviewed_at": "2026-10-12T16:30:00Z",
                  "reviewed_by": "reviewer@example.com",
                  "review_reason": "Shared device across three new accounts.",
                  "notes_count": 0,
                  "sharing_mode": "global",
                  "cross_org_available": true,
                  "cross_org_unavailable_reason": null,
                  "tags": [
                    {
                      "uuid": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
                      "name": "SUSPICIOUS",
                      "color": "#6366F1",
                      "source": "custom",
                      "added_by": null,
                      "added_at": "2026-10-13T08:15:00Z"
                    }
                  ],
                  "outcomes": {
                    "approved": 1,
                    "declined": 1,
                    "in_review": 0,
                    "total": 3
                  },
                  "patterns": [
                    {
                      "type": "background",
                      "score": 0.8125,
                      "members": 3,
                      "reason": null,
                      "computed_at": "2026-10-13T08:00:00Z"
                    }
                  ]
                }
              }
            }
          },
          "200": {
            "description": "Tag sudah ada di jaringan dan dibiarkan apa adanya. Mengembalikan detail jaringan.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NetworkDetailResponse"
                },
                "example": {
                  "uuid": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                  "network_id": "N-0042",
                  "name": null,
                  "status": "in_review",
                  "risk": {
                    "score": 82,
                    "band": "high",
                    "bar": 0.82
                  },
                  "pattern_types": [
                    "exact_same_device",
                    "same_email"
                  ],
                  "signal_types": [
                    "device",
                    "email"
                  ],
                  "member_counts": {
                    "total": 3,
                    "users": 3,
                    "businesses": 0,
                    "transaction_parties": 0
                  },
                  "member_status": {
                    "approved": 1,
                    "declined": 1,
                    "in_review": 0,
                    "not_completed": 1
                  },
                  "signal_coverage": {
                    "device": {
                      "signals": 1,
                      "subjects": 3,
                      "coverage": 1.0
                    },
                    "email": {
                      "signals": 1,
                      "subjects": 2,
                      "coverage": 0.6667
                    }
                  },
                  "first_activity_at": "2026-10-01T09:12:44Z",
                  "last_activity_at": "2026-10-12T16:03:10Z",
                  "stats": {
                    "members": {
                      "total": 3,
                      "users": 3,
                      "businesses": 0,
                      "transaction_parties": 0
                    },
                    "member_status": {
                      "approved": 1,
                      "declined": 1,
                      "in_review": 0,
                      "not_completed": 1
                    },
                    "signals": {
                      "total": 2,
                      "by_type": {
                        "device": {
                          "signals": 1,
                          "subjects": 3,
                          "coverage": 1.0
                        },
                        "email": {
                          "signals": 1,
                          "subjects": 2,
                          "coverage": 0.6667
                        }
                      }
                    }
                  },
                  "fraud_tags": [],
                  "risk_signals": {
                    "residential_proxy_reuse": {
                      "detected": false,
                      "signal_count": 0,
                      "max_subject_count": 0
                    },
                    "email_intelligence": {
                      "enriched_signal_count": 1,
                      "high_risk_count": 0,
                      "social_profile_count": 0
                    },
                    "phone_intelligence": {
                      "enriched_signal_count": 0,
                      "high_risk_count": 0
                    }
                  },
                  "reviewed_at": "2026-10-12T16:30:00Z",
                  "reviewed_by": "reviewer@example.com",
                  "review_reason": "Shared device across three new accounts.",
                  "notes_count": 0,
                  "sharing_mode": "global",
                  "cross_org_available": true,
                  "cross_org_unavailable_reason": null,
                  "tags": [
                    {
                      "uuid": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
                      "name": "SUSPICIOUS",
                      "color": "#6366F1",
                      "source": "custom",
                      "added_by": null,
                      "added_at": "2026-10-13T08:15:00Z"
                    }
                  ],
                  "outcomes": {
                    "approved": 1,
                    "declined": 1,
                    "in_review": 0,
                    "total": 3
                  },
                  "patterns": [
                    {
                      "type": "background",
                      "score": 0.8125,
                      "members": 3,
                      "reason": null,
                      "computed_at": "2026-10-13T08:00:00Z"
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Body tidak valid: `tag_uuid` hilang atau bukan UUID.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "tag_uuid": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                },
                "examples": {
                  "Missing tag_uuid": {
                    "summary": "tag_uuid tidak ada",
                    "value": {
                      "tag_uuid": [
                        "This field is required."
                      ]
                    }
                  },
                  "Invalid tag_uuid": {
                    "summary": "tag_uuid tidak valid",
                    "value": {
                      "tag_uuid": [
                        "Must be a valid UUID."
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Kredensial tidak ada atau tidak valid.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string",
                      "description": "Hadir pada error berkode, misalnya `networks_not_entitled`."
                    }
                  }
                },
                "examples": {
                  "Missing or invalid credentials": {
                    "summary": "Kredensial tidak ada atau tidak valid",
                    "value": {
                      "detail": "Authentication credentials were not provided or are invalid."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Kunci API milik aplikasi lain, atau merupakan kunci dengan akses terbatas: Endpoint Networks memerlukan kunci akses penuh. Token anggota konsol memerlukan `write:networks`. Juga dikembalikan dengan `code: networks_not_entitled` saat Networks tidak diaktifkan untuk organisasi.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string",
                      "description": "Hadir pada error berkode, misalnya `networks_not_entitled`."
                    }
                  }
                },
                "examples": {
                  "Networks not enabled": {
                    "summary": "Jaringan tidak diaktifkan",
                    "value": {
                      "detail": "Networks is disabled for this organization. Contact Didit support if you believe this is an error.",
                      "code": "networks_not_entitled"
                    }
                  },
                  "Restricted API key": {
                    "summary": "Kunci API terbatas",
                    "value": {
                      "detail": "This API key has no access to this endpoint."
                    }
                  },
                  "No permission": {
                    "summary": "Tidak ada izin",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Tidak ditemukan.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string",
                      "description": "Hadir pada error berkode, misalnya `networks_not_entitled`."
                    }
                  }
                },
                "examples": {
                  "Network not found": {
                    "summary": "Jaringan tidak ditemukan",
                    "value": {
                      "detail": "Network not found."
                    }
                  },
                  "Tag not found": {
                    "summary": "Tag tidak ditemukan",
                    "value": {
                      "detail": "Tag not found."
                    }
                  }
                }
              }
            }
          }
        },
        "x-didit-sdk": {
          "resource": "networks",
          "method": "add_tag",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        }
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/networks/{network_uuid}/tags/remove/": {
      "post": {
        "summary": "Hapus tag dari jaringan",
        "description": "Hapus salah satu tag aplikasi Anda dari jaringan. Mengembalikan detail jaringan. 404 jika tag tidak ada di jaringan, atau bukan milik aplikasi Anda. Memerlukan kunci API akses penuh, atau `write:networks` untuk anggota konsol.",
        "operationId": "remove_network_tag",
        "tags": [
          "Networks"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID organisasi."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID aplikasi."
          },
          {
            "name": "network_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
            },
            "description": "UUID jaringan."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/NetworkTagRequest"
              },
              "example": {
                "tag_uuid": "7c9e6679-7425-40de-944b-e07fc1f90ae7"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/networks/3fa85f64-5717-4562-b3fc-2c963f66afa6/tags/remove/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"tag_uuid\": \"7c9e6679-7425-40de-944b-e07fc1f90ae7\"}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.networks.remove_tag(\n    \"3fa85f64-5717-4562-b3fc-2c963f66afa6\",\n    tag_uuid=\"7c9e6679-7425-40de-944b-e07fc1f90ae7\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.networks.removeTag(\"3fa85f64-5717-4562-b3fc-2c963f66afa6\", {\n  tag_uuid: \"7c9e6679-7425-40de-944b-e07fc1f90ae7\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Networks.RemoveTag(ctx, \"3fa85f64-5717-4562-b3fc-2c963f66afa6\", didit.NetworkTagRequest{\n\tTagUUID: \"7c9e6679-7425-40de-944b-e07fc1f90ae7\",\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.NetworkTagRequest;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.networks().removeTag(\"3fa85f64-5717-4562-b3fc-2c963f66afa6\", NetworkTagRequest.builder()\n        .tagUuid(\"7c9e6679-7425-40de-944b-e07fc1f90ae7\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->networks->removeTag('3fa85f64-5717-4562-b3fc-2c963f66afa6', [\n    'tag_uuid' => '7c9e6679-7425-40de-944b-e07fc1f90ae7',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.networks.remove_tag(\n  \"3fa85f64-5717-4562-b3fc-2c963f66afa6\",\n  tag_uuid: \"7c9e6679-7425-40de-944b-e07fc1f90ae7\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Networks.RemoveTagAsync(\"3fa85f64-5717-4562-b3fc-2c963f66afa6\", new NetworkTagRequest\n{\n    TagUuid = \"7c9e6679-7425-40de-944b-e07fc1f90ae7\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "Tag telah dihapus dari jaringan. Mengembalikan detail jaringan.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NetworkDetailResponse"
                },
                "example": {
                  "uuid": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                  "network_id": "N-0042",
                  "name": null,
                  "status": "in_review",
                  "risk": {
                    "score": 82,
                    "band": "high",
                    "bar": 0.82
                  },
                  "pattern_types": [
                    "exact_same_device",
                    "same_email"
                  ],
                  "signal_types": [
                    "device",
                    "email"
                  ],
                  "member_counts": {
                    "total": 3,
                    "users": 3,
                    "businesses": 0,
                    "transaction_parties": 0
                  },
                  "member_status": {
                    "approved": 1,
                    "declined": 1,
                    "in_review": 0,
                    "not_completed": 1
                  },
                  "signal_coverage": {
                    "device": {
                      "signals": 1,
                      "subjects": 3,
                      "coverage": 1.0
                    },
                    "email": {
                      "signals": 1,
                      "subjects": 2,
                      "coverage": 0.6667
                    }
                  },
                  "first_activity_at": "2026-10-01T09:12:44Z",
                  "last_activity_at": "2026-10-12T16:03:10Z",
                  "stats": {
                    "members": {
                      "total": 3,
                      "users": 3,
                      "businesses": 0,
                      "transaction_parties": 0
                    },
                    "member_status": {
                      "approved": 1,
                      "declined": 1,
                      "in_review": 0,
                      "not_completed": 1
                    },
                    "signals": {
                      "total": 2,
                      "by_type": {
                        "device": {
                          "signals": 1,
                          "subjects": 3,
                          "coverage": 1.0
                        },
                        "email": {
                          "signals": 1,
                          "subjects": 2,
                          "coverage": 0.6667
                        }
                      }
                    }
                  },
                  "fraud_tags": [],
                  "risk_signals": {
                    "residential_proxy_reuse": {
                      "detected": false,
                      "signal_count": 0,
                      "max_subject_count": 0
                    },
                    "email_intelligence": {
                      "enriched_signal_count": 1,
                      "high_risk_count": 0,
                      "social_profile_count": 0
                    },
                    "phone_intelligence": {
                      "enriched_signal_count": 0,
                      "high_risk_count": 0
                    }
                  },
                  "reviewed_at": "2026-10-12T16:30:00Z",
                  "reviewed_by": "reviewer@example.com",
                  "review_reason": "Shared device across three new accounts.",
                  "notes_count": 0,
                  "sharing_mode": "global",
                  "cross_org_available": true,
                  "cross_org_unavailable_reason": null,
                  "tags": [],
                  "outcomes": {
                    "approved": 1,
                    "declined": 1,
                    "in_review": 0,
                    "total": 3
                  },
                  "patterns": [
                    {
                      "type": "background",
                      "score": 0.8125,
                      "members": 3,
                      "reason": null,
                      "computed_at": "2026-10-13T08:00:00Z"
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Body tidak valid: `tag_uuid` hilang atau bukan UUID.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "tag_uuid": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                },
                "examples": {
                  "Missing tag_uuid": {
                    "summary": "tag_uuid tidak ada",
                    "value": {
                      "tag_uuid": [
                        "This field is required."
                      ]
                    }
                  },
                  "Invalid tag_uuid": {
                    "summary": "tag_uuid tidak valid",
                    "value": {
                      "tag_uuid": [
                        "Must be a valid UUID."
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Kredensial tidak ada atau tidak valid.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string",
                      "description": "Hadir pada error berkode, misalnya `networks_not_entitled`."
                    }
                  }
                },
                "examples": {
                  "Missing or invalid credentials": {
                    "summary": "Kredensial tidak ada atau tidak valid",
                    "value": {
                      "detail": "Authentication credentials were not provided or are invalid."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Kunci API milik aplikasi lain, atau merupakan kunci dengan akses terbatas: Endpoint Networks memerlukan kunci akses penuh. Token anggota konsol memerlukan `write:networks`. Juga dikembalikan dengan `code: networks_not_entitled` saat Networks tidak diaktifkan untuk organisasi.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string",
                      "description": "Hadir pada error berkode, misalnya `networks_not_entitled`."
                    }
                  }
                },
                "examples": {
                  "Networks not enabled": {
                    "summary": "Jaringan tidak diaktifkan",
                    "value": {
                      "detail": "Networks is disabled for this organization. Contact Didit support if you believe this is an error.",
                      "code": "networks_not_entitled"
                    }
                  },
                  "Restricted API key": {
                    "summary": "Kunci API terbatas",
                    "value": {
                      "detail": "This API key has no access to this endpoint."
                    }
                  },
                  "No permission": {
                    "summary": "Tidak ada izin",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Tidak ditemukan.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string",
                      "description": "Hadir pada error berkode, misalnya `networks_not_entitled`."
                    }
                  }
                },
                "examples": {
                  "Network not found": {
                    "summary": "Jaringan tidak ditemukan",
                    "value": {
                      "detail": "Network not found."
                    }
                  },
                  "Tag not found": {
                    "summary": "Tag tidak ditemukan",
                    "value": {
                      "detail": "Tag not found."
                    }
                  },
                  "Tag not on the network": {
                    "summary": "Tag tidak ada di jaringan",
                    "value": {
                      "detail": "This tag is not on the network."
                    }
                  }
                }
              }
            }
          }
        },
        "x-didit-sdk": {
          "resource": "networks",
          "method": "remove_tag",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        }
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/cases/{case_uuid}/requests/{request_uuid}/remind/": {
      "post": {
        "summary": "Ingatkan pelanggan tentang permintaan",
        "description": "Kirim kembali email permintaan pelanggan yang sedang menunggu, ke penerima terverifikasi yang sama, dengan konten yang sama. Anda dapat mengingatkan permintaan paling banyak sekali setiap 24 jam. Pengingat tidak mengubah hal lain: permintaan mempertahankan tenggat waktunya dan kasus mempertahankan statusnya. Setiap pengingat dicatat pada kasus sebagai event CUSTOMER_REQUEST dengan tindakan `reminded`. `delivery_status` pada respons menunjukkan bagaimana pengiriman pengingat ini berakhir: SENT, SIMULATED (email tidak dikirim), atau UNKNOWN (email mungkin telah diterima; email tidak dikirim kembali secara otomatis). `next_reminder_at` adalah waktu saat Anda dapat mengingatkan permintaan ini lagi. Mengembalikan 409 dengan `reason` jika pelanggan tidak lagi memiliki permintaan untuk dijawab, dan 429 dengan `retry_at` dan header `Retry-After` jika permintaan telah dikirimi pengingat dalam 24 jam terakhir. Memerlukan `write:cases`.",
        "operationId": "organization_application_cases_requests_remind_create",
        "parameters": [
          {
            "in": "path",
            "name": "organization_id",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true,
            "description": "UUID organisasi."
          },
          {
            "in": "path",
            "name": "application_id",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true,
            "description": "UUID aplikasi."
          },
          {
            "in": "path",
            "name": "case_uuid",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true,
            "description": "UUID kasus."
          },
          {
            "in": "path",
            "name": "request_uuid",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true,
            "description": "UUID permintaan pelanggan, dari daftar permintaan kasus."
          }
        ],
        "tags": [
          "Case Management"
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/cases/c1a5e000-0000-4000-8000-000000000001/requests/3fa85f64-5717-4562-b3fc-2c963f66afa6/remind/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nresult = client.cases.requests.remind(\n    \"11111111-2222-3333-4444-555555555555\",\n    \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nconst result = await didit.cases.requests.remind(\n  \"11111111-2222-3333-4444-555555555555\",\n  \"11111111-2222-3333-4444-555555555555\",\n);\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nclient := didit.NewClient()\n\nresult, err := client.Cases.Requests.Remind(ctx, \"11111111-2222-3333-4444-555555555555\", \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nvar result = client.cases().requests().remind(\"11111111-2222-3333-4444-555555555555\", \"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$result = $didit->cases->requests->remind('11111111-2222-3333-4444-555555555555', '11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\nresult = didit.cases.requests.remind(\n  \"11111111-2222-3333-4444-555555555555\",\n  \"11111111-2222-3333-4444-555555555555\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nvar result = await client.Cases.Requests.RemindAsync(\"11111111-2222-3333-4444-555555555555\", \"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "Pengingat telah dicatat dan emailnya telah dikirim.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "request",
                    "reminded_at",
                    "delivery_status",
                    "next_reminder_at"
                  ],
                  "properties": {
                    "request": {
                      "$ref": "#/components/schemas/CustomerMessagingCaseRequest"
                    },
                    "reminded_at": {
                      "type": "string",
                      "format": "date-time",
                      "description": "Kapan pengingat ini dicatat."
                    },
                    "delivery_status": {
                      "type": "string",
                      "enum": [
                        "SENT",
                        "SIMULATED",
                        "UNKNOWN"
                      ],
                      "description": "Bagaimana pengiriman pengingat ini berakhir. SIMULATED: email tidak dikirim. UNKNOWN: email mungkin telah diterima; email ini tidak dikirim ulang secara otomatis."
                    },
                    "next_reminder_at": {
                      "type": "string",
                      "format": "date-time",
                      "description": "Kapan Anda dapat mengingatkan permintaan ini lagi: `reminded_at` ditambah 24 jam."
                    }
                  }
                },
                "example": {
                  "request": {
                    "uuid": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                    "purpose": "confirm_details",
                    "language": "en",
                    "recipient": "customer@example.com",
                    "expires_at": "2026-10-20T09:00:00Z",
                    "actor_email": "reviewer@example.com",
                    "delivery_status": "SENT",
                    "delivered_at": "2026-10-13T09:00:04Z",
                    "cancelled_at": null,
                    "responded_at": null,
                    "response": null,
                    "has_attachment": false,
                    "created_at": "2026-10-13T09:00:00Z"
                  },
                  "reminded_at": "2026-10-14T10:30:00Z",
                  "delivery_status": "SENT",
                  "next_reminder_at": "2026-10-15T10:30:00Z"
                }
              }
            }
          },
          "400": {
            "description": "Kasus memiliki resolusi yang menunggu persetujuan. Isi body berupa daftar string.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                },
                "example": [
                  "Customer messages require an active case without a pending resolution."
                ]
              }
            }
          },
          "403": {
            "description": "Pemanggil tidak memiliki izin kasus yang diperlukan."
          },
          "404": {
            "description": "Permintaan atau kasus tidak tersedia untuk pemanggil ini."
          },
          "409": {
            "description": "Permintaan tidak lagi menunggu pelanggan, sehingga tidak ada yang perlu diingatkan kepada mereka. `reason` menjelaskan alasannya: `answered` (pelanggan telah merespons), `cancelled`, `expired`, `closed` (kasus telah diselesaikan setelah permintaan dikirim, meskipun telah dibuka kembali sejak saat itu), `not_actionable` (pembaruan peninjauan yang sedang berlangsung tidak meminta apa pun), `not_delivered` (email pertama belum terkirim), atau `contact_unavailable` (email terverifikasi tidak lagi tersedia).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string",
                      "enum": [
                        "case_request_not_waiting"
                      ]
                    },
                    "reason": {
                      "type": "string",
                      "enum": [
                        "answered",
                        "cancelled",
                        "expired",
                        "closed",
                        "not_actionable",
                        "not_delivered",
                        "contact_unavailable"
                      ]
                    }
                  }
                },
                "example": {
                  "detail": "This request no longer waits on the customer, so there is nothing to remind them of.",
                  "code": "case_request_not_waiting",
                  "reason": "answered"
                }
              }
            }
          },
          "429": {
            "description": "Permintaan telah diingatkan dalam 24 jam terakhir. `retry_at` dan header `Retry-After` menunjukkan kapan Anda dapat mengingatkannya kembali.",
            "headers": {
              "Retry-After": {
                "description": "Detik untuk menunggu sebelum Anda dapat mengingatkan permintaan ini lagi.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "example": 3600
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string",
                      "enum": [
                        "case_request_reminder_too_soon"
                      ]
                    },
                    "retry_at": {
                      "type": "string",
                      "format": "date-time"
                    }
                  }
                },
                "example": {
                  "detail": "This request was already reminded in the last 24 hours.",
                  "code": "case_request_reminder_too_soon",
                  "retry_at": "2026-10-15T10:30:00Z"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-didit-sdk": {
          "resource": "cases.requests",
          "method": "remind",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        }
      }
    },
    "/v3/session/{sessionId}/decision-email-preview/": {
      "post": {
        "summary": "Pratinjau email keputusan sesi",
        "description": "Render email yang diterima seseorang saat Anda menetapkan sesi ke `Approved` atau `Declined` dengan `send_email: true`, tanpa mengubah sesi atau mengirimkan apa pun. Respons menampilkan subjek dan HTML persis seperti yang dikirimkan, penerima, pengirim, bahasa, dan apakah mengonfirmasi perubahan akan mengirimkan email sama sekali (`will_be_sent`, `not_sent_reason`).\n\nPenerima adalah alamat orang itu sendiri: alamat yang mereka verifikasi dalam langkah verifikasi email pada alur, atau alamat yang diberikan di `contact_details` saat sesi dibuat. Pengirim adalah domain pengirim terverifikasi aplikasi Anda jika White Label berlaku (`sender_kind: customer`), jika tidak, pengirim Didit (`sender_kind: didit`).\n\nUntuk mengirimkan persis apa yang Anda pratinjau, panggil [Update Session Status](/id/sessions-api/update-status) dengan `new_status` yang sama, `send_email: true`, `email_address` disetel ke `recipient`, `email_language` disetel ke `language`, dan `email_preview_token` disetel ke `preview_token`. Tanda terima kedaluwarsa setelah 15 menit. Jika penerima, bahasa, status sesi, pengirim, atau email berubah sejak pratinjau, pembaruan akan mengembalikan `409` sebelum ada yang berubah; lakukan pratinjau lagi dan konfirmasikan dengan tanda terima baru.\n\nBerfungsi untuk sesi Verifikasi Pengguna (KYC) dan Verifikasi Bisnis (KYB) dalam status `Approved`, `Declined`, `In Review`, `Kyc Expired`, `Abandoned`, atau `Resubmitted`. Pemeriksaan status berjalan sebelum validasi isi. Memerlukan hak istimewa `write:sessions`; kunci API dengan cakupan memerlukan akses tulis ke keputusan. Respons menggunakan `Cache-Control: no-store`: perlakukan sebagai konten verifikasi sensitif.",
        "operationId": "post_v3_session_decision_email_preview",
        "tags": [
          "Sessions"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "in": "path",
            "name": "sessionId",
            "required": true,
            "description": "UUID sesi verifikasi. Menerima ID sesi pengguna (KYC) dan bisnis (KYB).",
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "new_status"
                ],
                "properties": {
                  "new_status": {
                    "type": "string",
                    "enum": [
                      "Approved",
                      "Declined"
                    ],
                    "description": "Keputusan yang email-nya ingin Anda pratinjau.",
                    "example": "Approved"
                  },
                  "email_language": {
                    "type": "string",
                    "default": "en",
                    "description": "Bahasa email, default yang sama dengan Perbarui Status Sesi. Bahasa yang tidak ditawarkan beralih ke bahasa Inggris; `language` dalam respons menunjukkan bahasa mana yang digunakan.",
                    "example": "en"
                  }
                }
              },
              "examples": {
                "Approved": {
                  "summary": "Pratinjau email Disetujui dalam bahasa Inggris",
                  "value": {
                    "new_status": "Approved"
                  }
                },
                "Declined in Spanish": {
                  "summary": "Pratinjau email Ditolak dalam bahasa Spanyol",
                  "value": {
                    "new_status": "Declined",
                    "email_language": "es"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Hanya pratinjau. Sesi tidak berubah dan tidak ada email yang dikirim.",
            "headers": {
              "Cache-Control": {
                "description": "Selalu `no-store`: pratinjau memuat konten verifikasi dan tidak boleh disimpan dalam cache.",
                "schema": {
                  "type": "string",
                  "example": "no-store"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "recipient",
                    "recipient_source",
                    "sender",
                    "sender_name",
                    "sender_email",
                    "sender_kind",
                    "subject",
                    "html",
                    "text",
                    "language",
                    "will_be_sent",
                    "not_sent_reason",
                    "preview_token"
                  ],
                  "properties": {
                    "recipient": {
                      "type": "string",
                      "description": "Alamat tujuan pengiriman email. String kosong jika tidak ada alamat yang diketahui untuk orang tersebut: maka tidak ada email yang dapat dikirim dan `preview_token` juga kosong. Teruskan sebagai `email_address` saat Anda mengonfirmasi.",
                      "example": "person@example.com"
                    },
                    "recipient_source": {
                      "type": "string",
                      "enum": [
                        "email_verification",
                        "contact_details",
                        ""
                      ],
                      "description": "Dari mana asal `recipient`. `email_verification`: alamat yang diverifikasi orang tersebut dalam langkah verifikasi email pada alur. `contact_details`: alamat yang diberikan dalam `contact_details` saat sesi dibuat. Berupa string kosong jika tidak ada alamat.",
                      "example": "email_verification"
                    },
                    "sender": {
                      "type": "string",
                      "description": "Header `From` yang digunakan untuk mengirim email.",
                      "example": "Example App <no-reply@mail.example.com>"
                    },
                    "sender_name": {
                      "type": "string",
                      "description": "Bagian nama tampilan dari `sender`.",
                      "example": "Example App"
                    },
                    "sender_email": {
                      "type": "string",
                      "format": "email",
                      "description": "Bagian alamat dari `sender`.",
                      "example": "no-reply@mail.example.com"
                    },
                    "sender_kind": {
                      "type": "string",
                      "enum": [
                        "customer",
                        "didit"
                      ],
                      "description": "`customer`: email dikirim dari domain pengirim terverifikasi aplikasi Anda (White Label). `didit`: email dikirim dari pengirim Didit sendiri.",
                      "example": "customer"
                    },
                    "subject": {
                      "type": "string",
                      "description": "Baris subjek persis seperti yang dikirimkan.",
                      "example": "Your verification has been approved in Example App"
                    },
                    "html": {
                      "type": "string",
                      "description": "HTML email persis seperti yang dikirim, dengan logonya disematkan sebagai URL data. Render dalam frame sandbox, jangan pernah langsung di DOM aplikasi Anda.",
                      "example": "<!DOCTYPE html><html><body>...</body></html>"
                    },
                    "text": {
                      "type": "string",
                      "description": "Kata-kata email sebagai teks biasa, sebagaimana disimpan dalam utas Pesan orang tersebut, untuk pratinjau ringkas (HTML tetap berupa email yang diterima orang tersebut).",
                      "example": "Verification Approved\n\nYour identity has been successfully verified with Acme Pay. No further action is needed on your part."
                    },
                    "language": {
                      "type": "string",
                      "description": "Bahasa penulisan email. Bahasa Inggris (`en`) saat `email_language` yang Anda minta tidak tersedia.",
                      "example": "en"
                    },
                    "will_be_sent": {
                      "type": "boolean",
                      "description": "Menentukan apakah mengonfirmasi perubahan dengan `send_email: true` mengirimkan email ini. `false` jika `not_sent_reason` diatur.",
                      "example": true
                    },
                    "not_sent_reason": {
                      "type": "string",
                      "nullable": true,
                      "enum": [
                        "status_unchanged",
                        "notification_emails_disabled",
                        "no_recipient",
                        "sandbox",
                        null
                      ],
                      "description": "Alasan mengapa konfirmasi tidak akan mengirim email, atau `null` jika akan dikirim. `status_unchanged`: sesi sudah memiliki status ini, sehingga pembaruan tidak mengubah apa pun dan tidak mengirim apa pun. `notification_emails_disabled`: sesi dibuat tanpa `contact_details.send_notification_emails: true`, sehingga tidak ada email keputusan yang dikirim ke alamat yang diberikan di `contact_details`. `no_recipient`: tidak ada alamat yang diketahui untuk pengguna tersebut. `sandbox`: sesi sandbox yang penerimanya belum menyetujui pengiriman email sandbox, sehingga pengiriman hanya disimulasikan.",
                      "example": null
                    },
                    "preview_token": {
                      "type": "string",
                      "description": "Tanda terima yang ditandatangani untuk email persis ini, valid selama 15 menit. Teruskan sebagai `email_preview_token` ke [Perbarui Status Sesi](/id/sessions-api/update-status). String kosong jika tidak ada penerima.",
                      "example": "eyJkaWdlc3QiOiI0ZjJhIn0:1uExAm:Pl3x4mpleS1gnatureValue000000000000000"
                    }
                  }
                },
                "examples": {
                  "Will Be Sent": {
                    "summary": "Email Disetujui dikirim ke alamat yang diverifikasi dalam alur",
                    "value": {
                      "recipient": "person@example.com",
                      "recipient_source": "email_verification",
                      "sender": "Example App <no-reply@mail.example.com>",
                      "sender_name": "Example App",
                      "sender_email": "no-reply@mail.example.com",
                      "sender_kind": "customer",
                      "subject": "Your verification has been approved in Example App",
                      "html": "<!DOCTYPE html><html><body>...</body></html>",
                      "language": "en",
                      "will_be_sent": true,
                      "not_sent_reason": null,
                      "preview_token": "eyJkaWdlc3QiOiI0ZjJhIn0:1uExAm:Pl3x4mpleS1gnatureValue000000000000000"
                    }
                  },
                  "No Recipient": {
                    "summary": "Tidak ada alamat yang diketahui untuk orang tersebut",
                    "value": {
                      "recipient": "",
                      "recipient_source": "",
                      "sender": "Example App <no-reply@mail.example.com>",
                      "sender_name": "Example App",
                      "sender_email": "no-reply@mail.example.com",
                      "sender_kind": "customer",
                      "subject": "Your verification has been declined in Example App",
                      "html": "<!DOCTYPE html><html><body>...</body></html>",
                      "language": "en",
                      "will_be_sent": false,
                      "not_sent_reason": "no_recipient",
                      "preview_token": ""
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Sesi tidak berada dalam status yang diterima endpoint ini (`{\"detail\": ...}`), atau isi permintaan tidak valid (`{\"<field>\": [\"<message>\"]}`).",
            "content": {
              "application/json": {
                "examples": {
                  "Wrong Current Status": {
                    "summary": "Sesi tidak berada dalam status yang diterima oleh endpoint ini",
                    "value": {
                      "detail": "Only sessions with status Approved, Declined, In Review, Kyc Expired, Abandoned, Resubmitted can be updated. Current status: In Progress"
                    }
                  },
                  "Invalid new_status": {
                    "summary": "new_status bukan Approved atau Declined",
                    "value": {
                      "new_status": [
                        "\"Resubmitted\" is not a valid choice."
                      ]
                    }
                  },
                  "Missing new_status": {
                    "summary": "Kolom wajib tidak disertakan",
                    "value": {
                      "new_status": [
                        "This field is required."
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Kunci API dengan cakupan terbatas telah kedaluwarsa.",
            "content": {
              "application/json": {
                "examples": {
                  "Expired API Key": {
                    "summary": "Kunci API ber-scope melewati tanggal kedaluwarsanya",
                    "value": {
                      "detail": "This API key has expired."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Kredensial tidak ada, pemanggil tanpa hak istimewa `write:sessions`, kunci API dengan pembatasan cakupan tanpa akses yang dibutuhkan endpoint ini, atau `session_id` milik aplikasi lain.",
            "content": {
              "application/json": {
                "examples": {
                  "Invalid Credentials": {
                    "summary": "x-api-key tidak ada atau tidak valid",
                    "value": {
                      "detail": "Authentication credentials were not provided or are invalid."
                    }
                  },
                  "Missing Privilege": {
                    "summary": "Pemanggil tidak memiliki izin write:sessions",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Scoped Key Without Access": {
                    "summary": "Kunci API ber-scope tanpa akses ini",
                    "value": {
                      "detail": "This API key has no write access to decisions."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Tidak ada sesi KYC atau KYB dengan `session_id` ini.",
            "content": {
              "application/json": {
                "examples": {
                  "Not Found": {
                    "summary": "session_id tidak dikenal",
                    "value": {
                      "detail": "Not found."
                    }
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST \\\n  https://verification.didit.me/v3/session/3fa85f64-5717-4562-b3fc-2c963f66afa6/decision-email-preview/ \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"new_status\": \"Approved\", \"email_language\": \"en\"}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.preview_decision_email(\n    \"3fa85f64-5717-4562-b3fc-2c963f66afa6\",\n    new_status=\"Approved\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.previewDecisionEmail(\"3fa85f64-5717-4562-b3fc-2c963f66afa6\", {\n  new_status: \"Approved\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.PreviewDecisionEmail(ctx, \"3fa85f64-5717-4562-b3fc-2c963f66afa6\", didit.SessionsPreviewDecisionEmailParams{\n\tNewStatus: \"Approved\",\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.SessionsPreviewDecisionEmailParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().previewDecisionEmail(\"3fa85f64-5717-4562-b3fc-2c963f66afa6\", SessionsPreviewDecisionEmailParams.builder()\n        .newStatus(SessionsPreviewDecisionEmailParams.NewStatus.of(\"Approved\"))\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->sessions->previewDecisionEmail('3fa85f64-5717-4562-b3fc-2c963f66afa6', [\n    'new_status' => 'Approved',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.preview_decision_email(\n  \"3fa85f64-5717-4562-b3fc-2c963f66afa6\",\n  new_status: \"Approved\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.PreviewDecisionEmailAsync(\"3fa85f64-5717-4562-b3fc-2c963f66afa6\", new SessionsPreviewDecisionEmailParams\n{\n    NewStatus = \"Approved\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "x-didit-sdk": {
          "resource": "sessions",
          "method": "preview_decision_email",
          "auth": "api_key",
          "server": true
        }
      }
    },
    "/v3/travel-rule/join/{token}/": {
      "get": {
        "summary": "Dapatkan undangan bergabung gratis",
        "description": "Publik, tidak terautentikasi. Menampilkan undangan yang dituju oleh tautan gabung saat masih terbuka: siapa yang meminta, alamat tujuannya, dan nilai direktori yang akan diisi sebelumnya. Token berfungsi sebagai autentikasi.",
        "operationId": "getTravelRuleJoinInvitation",
        "x-didit-sdk": {
          "resource": "travel_rule.join",
          "method": "get_invitation",
          "auth": "public",
          "server": false
        },
        "tags": [
          "Travel Rule"
        ],
        "security": [
          {}
        ],
        "parameters": [
          {
            "name": "token",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Token undangan dari tautan untuk bergabung."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl https://verification.didit.me/v3/travel-rule/join/{token}/"
          }
        ],
        "responses": {
          "200": {
            "description": "Undangan.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TravelRuleJoinInvitation"
                }
              }
            }
          },
          "404": {
            "description": "Tidak ada undangan yang memiliki tautan ini."
          },
          "410": {
            "description": "Undangan tidak lagi terbuka: kedaluwarsa, sudah digunakan, atau ditarik kembali."
          }
        }
      },
      "post": {
        "summary": "Daftar akun Travel Rule gratis",
        "description": "Publik, tidak terautentikasi. Membuat akun Travel Rule gratis untuk VASP pihak lawan yang menerima permintaan. Email harus berupa alamat tujuan pengiriman undangan. Kode 6 karakter dikirimkan melalui email ke alamat tersebut; kirimkan ke endpoint verifikasi untuk menyelesaikannya. Percobaan pendaftaran dikenai batas laju per alamat dan per IP.",
        "operationId": "registerTravelRuleJoin",
        "x-didit-sdk": {
          "resource": "travel_rule.join",
          "method": "register",
          "auth": "public",
          "server": false
        },
        "tags": [
          "Travel Rule"
        ],
        "security": [
          {}
        ],
        "parameters": [
          {
            "name": "token",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Token undangan dari tautan untuk bergabung."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TravelRuleJoinRegisterRequest"
              },
              "example": {
                "email": "compliance@example.com",
                "password": "a-long-passphrase"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST https://verification.didit.me/v3/travel-rule/join/{token}/ \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"email\": \"compliance@example.com\", \"password\": \"a-long-passphrase\"}'"
          }
        ],
        "responses": {
          "202": {
            "description": "Akun berhasil dibuat dan kode telah dikirim melalui email.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string",
                      "description": "Memberitahukan pihak lawan untuk memeriksa email mereka guna mendapatkan kode verifikasi."
                    },
                    "email": {
                      "type": "string",
                      "format": "email",
                      "description": "Alamat tujuan pengiriman kode."
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Alamat email tersebut bukan alamat yang diundang, atau kata sandi atau alamat ditolak."
          },
          "404": {
            "description": "Tidak ada undangan yang memiliki tautan ini."
          },
          "410": {
            "description": "Undangan tidak lagi terbuka: kedaluwarsa, sudah digunakan, atau ditarik kembali."
          },
          "429": {
            "description": "Terlalu banyak upaya untuk bergabung. Header `X-RateLimit-*` menyebutkan kuota yang telah terpakai."
          }
        }
      }
    },
    "/v3/travel-rule/join/{token}/verify/": {
      "post": {
        "summary": "Verifikasi akun Travel Rule gratis",
        "description": "Publik, tidak terautentikasi. Menggunakan kode yang dikirim melalui email, membuat organisasi gratis, dan merespons dengan kredensial yang digunakan aplikasinya pada endpoint ruang kerja. Menerima data Travel Rule bersifat gratis.",
        "operationId": "verifyTravelRuleJoin",
        "x-didit-sdk": {
          "resource": "travel_rule.join",
          "method": "verify",
          "auth": "public",
          "server": false
        },
        "tags": [
          "Travel Rule"
        ],
        "security": [
          {}
        ],
        "parameters": [
          {
            "name": "token",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Token undangan dari tautan untuk bergabung."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TravelRuleJoinVerifyRequest"
              },
              "example": {
                "email": "compliance@example.com",
                "code": "123456"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST https://verification.didit.me/v3/travel-rule/join/{token}/verify/ \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"email\": \"compliance@example.com\", \"code\": \"123456\"}'"
          }
        ],
        "responses": {
          "201": {
            "description": "Kredensial organisasi dan aplikasi.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TravelRuleJoinCredentials"
                }
              }
            }
          },
          "400": {
            "description": "Kode atau email ditolak."
          },
          "404": {
            "description": "Tidak ada undangan yang memiliki tautan ini."
          },
          "410": {
            "description": "Undangan tidak lagi terbuka: kedaluwarsa, sudah digunakan, atau ditarik kembali."
          },
          "429": {
            "description": "Terlalu banyak upaya untuk bergabung. Header `X-RateLimit-*` menyebutkan kuota yang telah terpakai."
          }
        }
      }
    },
    "/v3/travel-rule/workspace/": {
      "get": {
        "summary": "Dapatkan ruang kerja Travel Rule gratis",
        "description": "Membaca ruang kerja gratis dari aplikasi yang bergabung secara gratis: klaim direktori, bukti domain, penagihan, dan daftar jaringan Didit.",
        "operationId": "getTravelRuleWorkspace",
        "x-didit-sdk": {
          "resource": "travel_rule.workspace",
          "method": "get",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Travel Rule"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET https://verification.didit.me/v3/travel-rule/workspace/ \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.travel_rule.workspace.get()\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.travelRule.workspace.get();\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.TravelRule.Workspace.Get(ctx)\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.travelRule().workspace().get();\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->travelRule->workspace->get();\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.travel_rule.workspace.get\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.TravelRule.Workspace.GetAsync();\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "Ruang kerja.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TravelRuleWorkspace"
                }
              }
            }
          },
          "404": {
            "description": "Aplikasi ini tidak bergabung secara gratis, sehingga tidak memiliki ruang kerja gratis."
          }
        }
      }
    },
    "/v3/travel-rule/workspace/claim/": {
      "post": {
        "summary": "Klaim entri direktori",
        "description": "Mengklaim entri direktori yang merupakan ruang kerja ini. Jika email kerja berada pada domain yang tercantum dalam entri tersebut, klaim terbukti dan langsung berlaku: profil VASP dan pengaturan Travel Rule diisi dari entri tersebut dan Travel Rule diaktifkan, sehingga transfer berikutnya ke entri tersebut diarahkan melalui jaringan Didit. Jika tidak, klaim menunggu peninjauan (`pending_review`).",
        "operationId": "claimTravelRuleWorkspace",
        "x-didit-sdk": {
          "resource": "travel_rule.workspace",
          "method": "claim",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Travel Rule"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TravelRuleWorkspaceClaimRequest"
              },
              "example": {
                "vasp_id": "0b0c9d3e-5a53-4a3e-9d6e-1f2f6f6a1c11"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST https://verification.didit.me/v3/travel-rule/workspace/claim/ \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"vasp_id\": \"0b0c9d3e-5a53-4a3e-9d6e-1f2f6f6a1c11\"}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.travel_rule.workspace.claim(\n    vasp_id=\"0b0c9d3e-5a53-4a3e-9d6e-1f2f6f6a1c11\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.travelRule.workspace.claim({\n  vasp_id: \"0b0c9d3e-5a53-4a3e-9d6e-1f2f6f6a1c11\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.TravelRule.Workspace.Claim(ctx, didit.TravelRuleWorkspaceClaimRequest{\n\tVASPID: \"0b0c9d3e-5a53-4a3e-9d6e-1f2f6f6a1c11\",\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.TravelRuleWorkspaceClaimRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.travelRule().workspace().claim(TravelRuleWorkspaceClaimRequest.builder()\n        .vaspId(\"0b0c9d3e-5a53-4a3e-9d6e-1f2f6f6a1c11\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->travelRule->workspace->claim([\n    'vasp_id' => '0b0c9d3e-5a53-4a3e-9d6e-1f2f6f6a1c11',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.travel_rule.workspace.claim(vasp_id: \"0b0c9d3e-5a53-4a3e-9d6e-1f2f6f6a1c11\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.TravelRule.Workspace.ClaimAsync(new TravelRuleWorkspaceClaimRequest\n{\n    VaspId = \"0b0c9d3e-5a53-4a3e-9d6e-1f2f6f6a1c11\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "Ruang kerja beserta status klaimnya.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TravelRuleWorkspace"
                }
              }
            }
          },
          "400": {
            "description": "Tidak ada entri direktori yang memiliki id ini."
          },
          "404": {
            "description": "Aplikasi ini tidak bergabung secara gratis, sehingga tidak memiliki ruang kerja gratis."
          }
        }
      }
    },
    "/v3/travel-rule/workspace/domain/code/": {
      "post": {
        "summary": "Kirim kode verifikasi domain melalui email",
        "description": "Mengirimkan kode sekali pakai ke alamat email kerja workspace untuk membuktikan kepemilikan domain email tersebut. Dibatasi, dan jumlah percobaan salah yang diterima per kode dibatasi. Juga mengembalikan data TXT untuk alternatif DNS.",
        "operationId": "sendTravelRuleWorkspaceDomainCode",
        "x-didit-sdk": {
          "resource": "travel_rule.workspace",
          "method": "send_domain_code",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Travel Rule"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST https://verification.didit.me/v3/travel-rule/workspace/domain/code/ \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.travel_rule.workspace.send_domain_code()\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.travelRule.workspace.sendDomainCode();\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.TravelRule.Workspace.SendDomainCode(ctx)\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.travelRule().workspace().sendDomainCode();\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->travelRule->workspace->sendDomainCode();\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.travel_rule.workspace.send_domain_code\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.TravelRule.Workspace.SendDomainCodeAsync();\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "Domain, statusnya, dan record TXT.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TravelRuleWorkspaceDomainCodeResponse"
                }
              }
            }
          },
          "404": {
            "description": "Aplikasi ini tidak bergabung secara gratis, sehingga tidak memiliki ruang kerja gratis."
          }
        }
      }
    },
    "/v3/travel-rule/workspace/domain/confirm/": {
      "post": {
        "summary": "Konfirmasikan kode verifikasi domain",
        "description": "Menggunakan kode yang dikirimkan melalui email dan menandai domain email telah diverifikasi.",
        "operationId": "confirmTravelRuleWorkspaceDomain",
        "x-didit-sdk": {
          "resource": "travel_rule.workspace",
          "method": "confirm_domain",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Travel Rule"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TravelRuleWorkspaceDomainConfirmRequest"
              },
              "example": {
                "code": "123456"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST https://verification.didit.me/v3/travel-rule/workspace/domain/confirm/ \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"code\": \"123456\"}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.travel_rule.workspace.confirm_domain(\n    code=\"123456\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.travelRule.workspace.confirmDomain({\n  code: \"123456\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.TravelRule.Workspace.ConfirmDomain(ctx, didit.TravelRuleWorkspaceDomainConfirmRequest{\n\tCode: \"123456\",\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.TravelRuleWorkspaceDomainConfirmRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.travelRule().workspace().confirmDomain(TravelRuleWorkspaceDomainConfirmRequest.builder()\n        .code(\"123456\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->travelRule->workspace->confirmDomain([\n    'code' => '123456',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.travel_rule.workspace.confirm_domain(code: \"123456\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.TravelRule.Workspace.ConfirmDomainAsync(new TravelRuleWorkspaceDomainConfirmRequest\n{\n    Code = \"123456\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "Ruang kerja.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TravelRuleWorkspace"
                }
              }
            }
          },
          "400": {
            "description": "Kode salah, kedaluwarsa, atau sudah digunakan."
          },
          "404": {
            "description": "Aplikasi ini tidak bergabung secara gratis, sehingga tidak memiliki ruang kerja gratis."
          }
        }
      }
    },
    "/v3/travel-rule/workspace/domain/dns/": {
      "post": {
        "summary": "Verifikasi domain dari data TXT miliknya",
        "description": "Memeriksa catatan TXT `didit-tr-verify.<domain>` yang dikembalikan oleh endpoint kode dan menandai domain sebagai terverifikasi jika cocok. Salah satu dari dua bukti, kode yang dikirim melalui email atau catatan TXT, sudah cukup.",
        "operationId": "verifyTravelRuleWorkspaceDomainDns",
        "x-didit-sdk": {
          "resource": "travel_rule.workspace",
          "method": "verify_domain_dns",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Travel Rule"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST https://verification.didit.me/v3/travel-rule/workspace/domain/dns/ \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.travel_rule.workspace.verify_domain_dns()\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.travelRule.workspace.verifyDomainDns();\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.TravelRule.Workspace.VerifyDomainDNS(ctx)\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.travelRule().workspace().verifyDomainDns();\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->travelRule->workspace->verifyDomainDns();\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.travel_rule.workspace.verify_domain_dns\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.TravelRule.Workspace.VerifyDomainDnsAsync();\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "Ruang kerja.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TravelRuleWorkspace"
                }
              }
            }
          },
          "400": {
            "description": "Record TXT tidak ditemukan atau tidak cocok."
          },
          "404": {
            "description": "Aplikasi ini tidak bergabung secara gratis, sehingga tidak memiliki ruang kerja gratis."
          }
        }
      }
    },
    "/v3/travel-rule/workspace/billing/": {
      "post": {
        "summary": "Aktifkan penagihan outbound",
        "description": "Mengaktifkan penagihan Travel Rule keluar untuk ruang kerja. Penerimaan tetap gratis. Ini tidak dapat dinonaktifkan kembali melalui API: hubungi dukungan Didit.",
        "operationId": "enableTravelRuleWorkspaceBilling",
        "x-didit-sdk": {
          "resource": "travel_rule.workspace",
          "method": "enable_billing",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Travel Rule"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TravelRuleWorkspaceBillingRequest"
              },
              "example": {
                "enabled": true
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST https://verification.didit.me/v3/travel-rule/workspace/billing/ \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"enabled\": true}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.travel_rule.workspace.enable_billing(\n    enabled=True,\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.travelRule.workspace.enableBilling({\n  enabled: true,\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.TravelRule.Workspace.EnableBilling(ctx, didit.TravelRuleWorkspaceBillingRequest{\n\tEnabled: didit.Bool(true),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.TravelRuleWorkspaceBillingRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.travelRule().workspace().enableBilling(TravelRuleWorkspaceBillingRequest.builder()\n        .enabled(true)\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->travelRule->workspace->enableBilling([\n    'enabled' => true,\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.travel_rule.workspace.enable_billing(enabled: true)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.TravelRule.Workspace.EnableBillingAsync(new TravelRuleWorkspaceBillingRequest\n{\n    Enabled = true,\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "Ruang kerja dengan `billing_enabled` bernilai true.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TravelRuleWorkspace"
                }
              }
            }
          },
          "400": {
            "description": "`enabled` bernilai false."
          },
          "404": {
            "description": "Aplikasi ini tidak bergabung secara gratis, sehingga tidak memiliki ruang kerja gratis."
          }
        }
      }
    },
    "/v3/investigator/summary/": {
      "get": {
        "operationId": "investigator_summary",
        "summary": "Ringkasan penyelidik",
        "description": "Tahap, jumlah antrean, laporan yang disiapkan dan diputuskan hari ini, kesepakatan 30 hari, harga, serta tingkat otonomi setiap antrean. Kunci yang dibatasi memerlukan cakupan `decisions` (baca); alert transaksi juga memerlukan `transactions`.",
        "tags": [
          "Investigator"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "properties": {
                    "stage": {
                      "type": "string"
                    },
                    "last_report_at": {
                      "type": "string",
                      "format": "date-time",
                      "nullable": true
                    },
                    "prepared_today": {
                      "type": "integer"
                    },
                    "ready_to_accept": {
                      "type": "integer"
                    },
                    "open": {
                      "type": "integer"
                    },
                    "decided_today": {
                      "type": "integer"
                    },
                    "automation_rate_month": {
                      "type": "number",
                      "nullable": true
                    },
                    "preparing": {
                      "type": "integer"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Kunci API tidak ada atau tidak valid."
          },
          "403": {
            "description": "Kunci tidak memiliki cakupan, jenis item tidak dapat dibaca, atau paket tidak mencakup Investigator."
          }
        },
        "parameters": [
          {
            "in": "query",
            "name": "scope",
            "schema": {
              "type": "string",
              "enum": [
                "all",
                "identity",
                "transactions"
              ],
              "default": "all"
            },
            "description": "`identity` (sesi, dan kasus yang tidak dibuka oleh aturan transaksi) atau `transactions` (alert transaksi, dan kasus yang dibuka oleh aturan transaksi)."
          },
          {
            "in": "query",
            "name": "timezone",
            "schema": {
              "type": "string"
            },
            "description": "Zona waktu IANA (misalnya `Europe/Madrid`) sebagai titik awal perhitungan \"hari ini\". Default-nya adalah UTC."
          }
        ],
        "x-didit-sdk": {
          "resource": "investigator",
          "method": "retrieve_summary",
          "auth": "api_key",
          "server": true
        },
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.investigator.retrieve_summary()\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.investigator.retrieveSummary();\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Investigator.RetrieveSummary(ctx, didit.InvestigatorRetrieveSummaryParams{})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.investigator().retrieveSummary();\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->investigator->retrieveSummary();\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.investigator.retrieve_summary\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Investigator.RetrieveSummaryAsync();\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/investigator/queue/": {
      "get": {
        "operationId": "investigator_queue",
        "summary": "Mencantumkan antrean investigator",
        "description": "Laporan terbuka, **Siap diterima** lebih dahulu, lalu berdasarkan tenggat waktu, risiko, dan waktu tunggu. `counts` mencakup setiap jenis dalam cakupan. `count` dibatasi maksimal 100. Kunci yang dibatasi memerlukan cakupan `decisions` (baca); alert transaksi juga memerlukan `transactions`.",
        "tags": [
          "Investigator"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "count": {
                      "type": "integer"
                    },
                    "next": {
                      "type": "string",
                      "nullable": true
                    },
                    "previous": {
                      "type": "string",
                      "nullable": true
                    },
                    "counts": {
                      "type": "object",
                      "additionalProperties": true
                    },
                    "results": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/InvestigatorQueueRow"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Kunci API tidak ada atau tidak valid."
          },
          "403": {
            "description": "Kunci tidak memiliki cakupan, jenis item tidak dapat dibaca, atau paket tidak mencakup Investigator."
          }
        },
        "parameters": [
          {
            "in": "query",
            "name": "scope",
            "schema": {
              "type": "string",
              "enum": [
                "all",
                "identity",
                "transactions"
              ],
              "default": "all"
            },
            "description": "`identity` (sesi, dan kasus yang tidak dibuka oleh aturan transaksi) atau `transactions` (alert transaksi, dan kasus yang dibuka oleh aturan transaksi)."
          },
          {
            "in": "query",
            "name": "kind",
            "schema": {
              "type": "string"
            },
            "description": "`session`, `business_session`, `transaction`, atau `case`, atau beberapa yang dipisahkan dengan koma."
          },
          {
            "in": "query",
            "name": "queue",
            "schema": {
              "type": "string",
              "enum": [
                "kyc",
                "kyb",
                "aml",
                "transactions",
                "cases"
              ]
            }
          },
          {
            "in": "query",
            "name": "recommendation",
            "schema": {
              "type": "string",
              "enum": [
                "approve",
                "decline",
                "escalate",
                "request"
              ]
            }
          },
          {
            "in": "query",
            "name": "confidence",
            "schema": {
              "type": "string",
              "enum": [
                "high",
                "moderate",
                "low"
              ]
            }
          },
          {
            "in": "query",
            "name": "ready",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "in": "query",
            "name": "search",
            "schema": {
              "type": "string"
            },
            "description": "Nama, perusahaan, judul kasus, nomor, ID transaksi, atau ID item."
          },
          {
            "in": "query",
            "name": "limit",
            "schema": {
              "type": "integer"
            }
          },
          {
            "in": "query",
            "name": "offset",
            "schema": {
              "type": "integer"
            }
          }
        ],
        "x-didit-sdk": {
          "resource": "investigator",
          "method": "list_queue",
          "auth": "api_key",
          "server": true
        },
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nfor item in client.investigator.list_queue():\n    print(item)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nfor await (const item of didit.investigator.listQueue()) {\n  console.log(item);\n}"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\niter := client.Investigator.ListQueueAutoPaging(ctx, didit.InvestigatorListQueueParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nfor (var item : client.investigator().listQueue()) {\n    System.out.println(item);\n}"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\nforeach ($didit->investigator->listQueue() as $item) {\n    print_r($item->toArray());\n}"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.investigator.list_queue.auto_paging_each do |item|\n  puts item.to_h\nend"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.Investigator.ListQueueAsync())\n{\n    Console.WriteLine(JsonSerializer.Serialize(item));\n}"
          }
        ]
      }
    },
    "/v3/investigator/runs/{run_id}/": {
      "get": {
        "operationId": "investigator_run_retrieve",
        "summary": "Dapatkan laporan Investigator",
        "description": "Laporan lengkap dari satu eksekusi. 404 jika eksekusi tidak memiliki laporan yang selesai, atau itemnya telah dihapus. Kunci terbatas memerlukan cakupan `decisions` (read); alert transaksi juga memerlukan `transactions`.",
        "tags": [
          "Investigator"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InvestigatorRunDetail"
                }
              }
            }
          },
          "404": {
            "description": "Tidak ditemukan, atau tidak ada laporan."
          },
          "401": {
            "description": "Kunci API tidak ada atau tidak valid."
          },
          "403": {
            "description": "Kunci tidak memiliki cakupan, jenis item tidak dapat dibaca, atau paket tidak mencakup Investigator."
          }
        },
        "parameters": [
          {
            "in": "path",
            "name": "run_id",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "x-didit-sdk": {
          "resource": "investigator",
          "method": "retrieve_run",
          "auth": "api_key",
          "server": true
        },
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.investigator.retrieve_run(\n    \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.investigator.retrieveRun(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Investigator.RetrieveRun(ctx, \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.investigator().retrieveRun(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->investigator->retrieveRun('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.investigator.retrieve_run(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Investigator.RetrieveRunAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/investigator/runs/{run_id}/accept/": {
      "post": {
        "operationId": "investigator_run_accept",
        "summary": "Menerima rekomendasi",
        "description": "Menerapkan tindakan yang direkomendasikan melalui jalur normal item, sehingga webhook biasa Anda terpicu. `narrative` menjadikannya diedit dan diterima. Kunci terbatas memerlukan cakupan `decisions` (tulis); alert transaksi juga memerlukan `transactions` (tulis). Mengeskalasikan verifikasi atau transaksi akan membuka kasus.",
        "tags": [
          "Investigator"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InvestigatorDecision"
                }
              }
            }
          },
          "409": {
            "description": "Sudah diputuskan, laporan belum siap, atau guardrail menahan item tersebut."
          },
          "401": {
            "description": "Kunci API tidak ada atau tidak valid."
          },
          "403": {
            "description": "Kunci tidak memiliki cakupan, jenis item tidak dapat dibaca, atau paket tidak mencakup Investigator."
          }
        },
        "parameters": [
          {
            "in": "path",
            "name": "run_id",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/InvestigatorAcceptRequest"
              },
              "example": {
                "send_email": false
              }
            }
          }
        },
        "x-didit-sdk": {
          "resource": "investigator",
          "method": "accept_run",
          "auth": "api_key",
          "server": true
        },
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.investigator.accept_run(\n    \"11111111-2222-3333-4444-555555555555\",\n    send_email=False,\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.investigator.acceptRun(\"11111111-2222-3333-4444-555555555555\", {\n  send_email: false,\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Investigator.AcceptRun(ctx, \"11111111-2222-3333-4444-555555555555\", didit.InvestigatorAcceptRequest{\n\tSendEmail: didit.Bool(false),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.InvestigatorAcceptRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.investigator().acceptRun(\"11111111-2222-3333-4444-555555555555\", InvestigatorAcceptRequest.builder()\n        .sendEmail(false)\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->investigator->acceptRun('11111111-2222-3333-4444-555555555555', [\n    'send_email' => false,\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.investigator.accept_run(\n  \"11111111-2222-3333-4444-555555555555\",\n  send_email: false\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Investigator.AcceptRunAsync(\"11111111-2222-3333-4444-555555555555\", new InvestigatorAcceptRequest\n{\n    SendEmail = false,\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/investigator/runs/{run_id}/override/": {
      "post": {
        "operationId": "investigator_run_override",
        "summary": "Timpa rekomendasi",
        "description": "Mengambil tindakan lain dengan kategori dan alasan. Juga mengesampingkan keputusan yang diambil oleh Investigator secara mandiri selama keputusan tersebut masih berlaku. Kunci terbatas memerlukan cakupan `decisions` (tulis); alert transaksi juga memerlukan `transactions` (tulis). Mengeskalasikan verifikasi atau transaksi akan membuka kasus.",
        "tags": [
          "Investigator"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InvestigatorDecision"
                }
              }
            }
          },
          "409": {
            "description": "Sudah diputuskan, atau guardrail menahan item tersebut."
          },
          "401": {
            "description": "Kunci API tidak ada atau tidak valid."
          },
          "403": {
            "description": "Kunci tidak memiliki cakupan, jenis item tidak dapat dibaca, atau paket tidak mencakup Investigator."
          }
        },
        "parameters": [
          {
            "in": "path",
            "name": "run_id",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/InvestigatorOverrideRequest"
              },
              "example": {
                "action": "decline",
                "category": "evidence_misread",
                "reason": "The proof of address is older than three months."
              }
            }
          }
        },
        "x-didit-sdk": {
          "resource": "investigator",
          "method": "override_run",
          "auth": "api_key",
          "server": true
        },
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.investigator.override_run(\n    \"11111111-2222-3333-4444-555555555555\",\n    action=\"decline\",\n    category=\"evidence_misread\",\n    reason=\"The proof of address is older than three months.\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.investigator.overrideRun(\"11111111-2222-3333-4444-555555555555\", {\n  action: \"decline\",\n  category: \"evidence_misread\",\n  reason: \"The proof of address is older than three months.\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Investigator.OverrideRun(ctx, \"11111111-2222-3333-4444-555555555555\", didit.InvestigatorOverrideRequest{\n\tAction:   \"decline\",\n\tCategory: \"evidence_misread\",\n\tReason:   \"The proof of address is older than three months.\",\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.InvestigatorOverrideRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.investigator().overrideRun(\"11111111-2222-3333-4444-555555555555\", InvestigatorOverrideRequest.builder()\n        .action(InvestigatorOverrideRequest.Action.of(\"decline\"))\n        .category(InvestigatorOverrideRequest.Category.of(\"evidence_misread\"))\n        .reason(\"The proof of address is older than three months.\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->investigator->overrideRun('11111111-2222-3333-4444-555555555555', [\n    'action' => 'decline',\n    'category' => 'evidence_misread',\n    'reason' => 'The proof of address is older than three months.',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.investigator.override_run(\n  \"11111111-2222-3333-4444-555555555555\",\n  action: \"decline\",\n  category: \"evidence_misread\",\n  reason: \"The proof of address is older than three months.\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Investigator.OverrideRunAsync(\"11111111-2222-3333-4444-555555555555\", new InvestigatorOverrideRequest\n{\n    Action = \"decline\",\n    Category = \"evidence_misread\",\n    Reason = \"The proof of address is older than three months.\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/investigator/runs/batch-accept/": {
      "post": {
        "operationId": "investigator_batch_accept",
        "summary": "Terima rekomendasi secara batch",
        "description": "Menerima hingga 50 laporan yang ditandai Siap diterima. Masing-masing merupakan keputusannya sendiri: laporan yang tidak dapat diterima akan dilewati beserta alasannya. Kunci terbatas memerlukan cakupan `decisions` (tulis); alert transaksi juga memerlukan `transactions` (tulis). Mengeskalasi verifikasi atau transaksi akan membuka kasus.",
        "tags": [
          "Investigator"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InvestigatorBatchAcceptResponse"
                }
              }
            }
          },
          "401": {
            "description": "Kunci API tidak ada atau tidak valid."
          },
          "403": {
            "description": "Kunci tidak memiliki cakupan, jenis item tidak dapat dibaca, atau paket tidak mencakup Investigator."
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/InvestigatorBatchAcceptRequest"
              }
            }
          }
        },
        "x-didit-sdk": {
          "resource": "investigator",
          "method": "batch_accept_runs",
          "auth": "api_key",
          "server": true
        },
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.investigator.batch_accept_runs(\n    run_ids=[\"11111111-2222-3333-4444-555555555555\"],\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.investigator.batchAcceptRuns({\n  run_ids: [\"11111111-2222-3333-4444-555555555555\"],\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Investigator.BatchAcceptRuns(ctx, didit.InvestigatorBatchAcceptRequest{\n\tRunIDs: []string{\"11111111-2222-3333-4444-555555555555\"},\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.List;\nimport me.didit.Didit;\nimport me.didit.types.InvestigatorBatchAcceptRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.investigator().batchAcceptRuns(InvestigatorBatchAcceptRequest.builder()\n        .runIds(List.of(\"11111111-2222-3333-4444-555555555555\"))\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->investigator->batchAcceptRuns([\n    'run_ids' => ['11111111-2222-3333-4444-555555555555'],\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.investigator.batch_accept_runs(run_ids: [\"11111111-2222-3333-4444-555555555555\"])\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Investigator.BatchAcceptRunsAsync(new InvestigatorBatchAcceptRequest\n{\n    RunIds = new string[] { \"11111111-2222-3333-4444-555555555555\" },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/investigator/transactions/{transaction_id}/": {
      "get": {
        "operationId": "investigator_transaction_retrieve",
        "summary": "Dapatkan peninjauan Investigator atas transaksi",
        "description": "Peninjauan terbaru transaksi, atau `investigator: null` jika transaksi tersebut belum pernah ditinjau. Kunci terbatas memerlukan cakupan `decisions` dan `transactions` (baca).",
        "tags": [
          "Investigator"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "transaction_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "investigator": {
                      "$ref": "#/components/schemas/InvestigatorBlock"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Bukan transaksi aplikasi ini."
          },
          "401": {
            "description": "Kunci API tidak ada atau tidak valid."
          },
          "403": {
            "description": "Kunci tidak memiliki cakupan, jenis item tidak dapat dibaca, atau paket tidak mencakup Investigator."
          }
        },
        "parameters": [
          {
            "in": "path",
            "name": "transaction_id",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "x-didit-sdk": {
          "resource": "investigator",
          "method": "retrieve_transaction",
          "auth": "api_key",
          "server": true
        },
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.investigator.retrieve_transaction(\n    \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.investigator.retrieveTransaction(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Investigator.RetrieveTransaction(ctx, \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.investigator().retrieveTransaction(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->investigator->retrieveTransaction('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.investigator.retrieve_transaction(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Investigator.RetrieveTransactionAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/investigator/guardrails/": {
      "get": {
        "operationId": "investigator_guardrails",
        "summary": "Mencantumkan daftar guardrail yang terkunci",
        "description": "Lima pengaman yang berlaku untuk setiap antrean. Pengaman ini tidak dapat dimatikan. Kunci terbatas memerlukan cakupan `decisions` (read); alert transaksi juga memerlukan `transactions`.",
        "tags": [
          "Investigator"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "results": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "key": {
                            "type": "string",
                            "enum": [
                              "sanctions_to_person",
                              "no_tipping_off",
                              "no_protected_characteristics",
                              "never_files_reports",
                              "every_decision_logged"
                            ]
                          },
                          "title": {
                            "type": "string"
                          },
                          "description": {
                            "type": "string"
                          },
                          "locked": {
                            "type": "boolean"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Kunci API tidak ada atau tidak valid."
          },
          "403": {
            "description": "Kunci tidak memiliki cakupan, jenis item tidak dapat dibaca, atau paket tidak mencakup Investigator."
          }
        },
        "x-didit-sdk": {
          "resource": "investigator",
          "method": "list_guardrails",
          "auth": "api_key",
          "server": true
        },
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.investigator.list_guardrails()\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.investigator.listGuardrails();\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Investigator.ListGuardrails(ctx)\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.investigator().listGuardrails();\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->investigator->listGuardrails();\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.investigator.list_guardrails\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Investigator.ListGuardrailsAsync();\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/investigator/dashboard/": {
      "get": {
        "operationId": "investigator_dashboard",
        "summary": "Dasbor penyelidik",
        "description": "30 hari terakhir: peninjauan, keputusan, tingkat otomatisasi, jam yang dihemat, pengeluaran, penimpaan, sampel kualitas sejak mulai beroperasi, angka per antrean dan mingguan. Kunci terbatas memerlukan cakupan `decisions` (baca); alert transaksi juga memerlukan `transactions`.",
        "tags": [
          "Investigator"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "properties": {
                    "stage": {
                      "type": "string"
                    },
                    "window_days": {
                      "type": "integer"
                    },
                    "reviews": {
                      "type": "integer"
                    },
                    "decided": {
                      "type": "integer"
                    },
                    "automated": {
                      "type": "integer"
                    },
                    "automation_rate": {
                      "type": "number",
                      "nullable": true
                    },
                    "hours_saved": {
                      "type": "number",
                      "nullable": true
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Kunci API tidak ada atau tidak valid."
          },
          "403": {
            "description": "Kunci tidak memiliki cakupan, jenis item tidak dapat dibaca, atau paket tidak mencakup Investigator."
          }
        },
        "parameters": [
          {
            "in": "query",
            "name": "scope",
            "schema": {
              "type": "string",
              "enum": [
                "all",
                "identity",
                "transactions"
              ],
              "default": "all"
            },
            "description": "`identity` (sesi, dan kasus yang tidak dibuka oleh aturan transaksi) atau `transactions` (alert transaksi, dan kasus yang dibuka oleh aturan transaksi)."
          }
        ],
        "x-didit-sdk": {
          "resource": "investigator",
          "method": "retrieve_dashboard",
          "auth": "api_key",
          "server": true
        },
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.investigator.retrieve_dashboard()\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.investigator.retrieveDashboard();\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Investigator.RetrieveDashboard(ctx, didit.InvestigatorRetrieveDashboardParams{})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.investigator().retrieveDashboard();\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->investigator->retrieveDashboard();\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.investigator.retrieve_dashboard\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Investigator.RetrieveDashboardAsync();\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/investigator/performance/": {
      "get": {
        "operationId": "investigator_performance",
        "summary": "Kinerja penyelidik",
        "description": "Kesesuaian dengan tim Anda, volume, waktu yang dihemat, kalibrasi keyakinan, hasil per antrean, alasan penimpaan, dan ketidaksesuaian untuk suatu periode. Kunci yang dibatasi memerlukan cakupan `decisions` (read); alert transaksi juga memerlukan `transactions`.",
        "tags": [
          "Investigator"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "properties": {
                    "period": {
                      "type": "integer"
                    },
                    "start": {
                      "type": "string",
                      "format": "date"
                    },
                    "end": {
                      "type": "string",
                      "format": "date"
                    },
                    "investigated": {
                      "type": "integer"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Kunci API tidak ada atau tidak valid."
          },
          "403": {
            "description": "Kunci tidak memiliki cakupan, jenis item tidak dapat dibaca, atau paket tidak mencakup Investigator."
          }
        },
        "parameters": [
          {
            "in": "query",
            "name": "scope",
            "schema": {
              "type": "string",
              "enum": [
                "all",
                "identity",
                "transactions"
              ],
              "default": "all"
            },
            "description": "`identity` (sesi, dan kasus yang tidak dibuka oleh aturan transaksi) atau `transactions` (alert transaksi, dan kasus yang dibuka oleh aturan transaksi)."
          },
          {
            "in": "query",
            "name": "period",
            "schema": {
              "type": "string",
              "enum": [
                "7",
                "30",
                "90"
              ],
              "default": "30"
            },
            "description": "Hari-hari yang berakhir hari ini."
          }
        ],
        "x-didit-sdk": {
          "resource": "investigator",
          "method": "retrieve_performance",
          "auth": "api_key",
          "server": true
        },
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.investigator.retrieve_performance()\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.investigator.retrievePerformance();\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Investigator.RetrievePerformance(ctx, didit.InvestigatorRetrievePerformanceParams{})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.investigator().retrievePerformance();\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->investigator->retrievePerformance();\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.investigator.retrieve_performance\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Investigator.RetrievePerformanceAsync();\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/investigator/activity/": {
      "get": {
        "operationId": "investigator_activity",
        "summary": "Daftar aktivitas Penyelidik",
        "description": "Jejak audit yang hanya dapat ditambahi, terbaru terlebih dahulu. Penerimaan batch adalah satu entri. Menambahkan `counts` per grup dan `actors`. Kunci yang dibatasi memerlukan cakupan `decisions` (baca); alert transaksi juga memerlukan `transactions`.",
        "tags": [
          "Investigator"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "count": {
                      "type": "integer"
                    },
                    "next": {
                      "type": "string",
                      "nullable": true
                    },
                    "previous": {
                      "type": "string",
                      "nullable": true
                    },
                    "counts": {
                      "type": "object",
                      "additionalProperties": true
                    },
                    "actors": {
                      "type": "array",
                      "items": {}
                    },
                    "results": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "additionalProperties": true,
                        "description": "`id`, `at`, `kind`, `group`, `queue`, `run_id`, `item`, `actor`, `agent_version`, `data`, `report_version`, `steps`, `sources`, `batch`."
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Kunci API tidak ada atau tidak valid."
          },
          "403": {
            "description": "Kunci tidak memiliki cakupan, jenis item tidak dapat dibaca, atau paket tidak mencakup Investigator."
          }
        },
        "parameters": [
          {
            "in": "query",
            "name": "scope",
            "schema": {
              "type": "string",
              "enum": [
                "all",
                "identity",
                "transactions"
              ],
              "default": "all"
            },
            "description": "`identity` (sesi, dan kasus yang tidak dibuka oleh aturan transaksi) atau `transactions` (alert transaksi, dan kasus yang dibuka oleh aturan transaksi)."
          },
          {
            "in": "query",
            "name": "group",
            "schema": {
              "type": "string",
              "enum": [
                "agent",
                "decisions",
                "overrides",
                "autonomy"
              ]
            }
          },
          {
            "in": "query",
            "name": "actor",
            "schema": {
              "type": "string"
            },
            "description": "`agent` untuk Investigator, atau email seseorang."
          },
          {
            "in": "query",
            "name": "since",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "in": "query",
            "name": "until",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "in": "query",
            "name": "limit",
            "schema": {
              "type": "integer"
            }
          },
          {
            "in": "query",
            "name": "offset",
            "schema": {
              "type": "integer"
            }
          }
        ],
        "x-didit-sdk": {
          "resource": "investigator",
          "method": "list_activity",
          "auth": "api_key",
          "server": true
        },
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nfor item in client.investigator.list_activity():\n    print(item)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nfor await (const item of didit.investigator.listActivity()) {\n  console.log(item);\n}"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\niter := client.Investigator.ListActivityAutoPaging(ctx, didit.InvestigatorListActivityParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nfor (var item : client.investigator().listActivity()) {\n    System.out.println(item);\n}"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\nforeach ($didit->investigator->listActivity() as $item) {\n    print_r($item);\n}"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.investigator.list_activity.auto_paging_each do |item|\n  puts item.to_h\nend"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.Investigator.ListActivityAsync())\n{\n    Console.WriteLine(JsonSerializer.Serialize(item));\n}"
          }
        ]
      }
    },
    "/v3/investigator/activity/export/": {
      "get": {
        "operationId": "investigator_activity_export",
        "summary": "Ekspor aktivitas Investigator",
        "description": "Entri yang sama dalam format CSV, satu baris per keputusan, yang terbaru lebih dulu, hingga 10.000 entri. Kunci terbatas memerlukan cakupan `decisions` (baca); alert transaksi juga memerlukan `transactions`.",
        "tags": [
          "Investigator"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "text/csv": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "description": "Kunci API tidak ada atau tidak valid."
          },
          "403": {
            "description": "Kunci tidak memiliki cakupan, jenis item tidak dapat dibaca, atau paket tidak mencakup Investigator."
          }
        },
        "parameters": [
          {
            "in": "query",
            "name": "scope",
            "schema": {
              "type": "string",
              "enum": [
                "all",
                "identity",
                "transactions"
              ],
              "default": "all"
            },
            "description": "`identity` (sesi, dan kasus yang tidak dibuka oleh aturan transaksi) atau `transactions` (alert transaksi, dan kasus yang dibuka oleh aturan transaksi)."
          },
          {
            "in": "query",
            "name": "group",
            "schema": {
              "type": "string",
              "enum": [
                "agent",
                "decisions",
                "overrides",
                "autonomy"
              ]
            }
          },
          {
            "in": "query",
            "name": "actor",
            "schema": {
              "type": "string"
            },
            "description": "`agent` untuk Investigator, atau email seseorang."
          },
          {
            "in": "query",
            "name": "since",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "in": "query",
            "name": "until",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          }
        ],
        "x-didit-sdk": {
          "resource": "investigator",
          "method": "export_activity",
          "auth": "api_key",
          "server": true
        },
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\ncontent = client.investigator.export_activity()\nwith open(\"download.csv\", \"wb\") as file:\n    file.write(content)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import { writeFile } from \"node:fs/promises\";\nimport Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst content = await didit.investigator.exportActivity();\nawait writeFile(\"download.csv\", Buffer.from(await content.arrayBuffer()));"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresp, err := client.Investigator.ExportActivity(ctx, didit.InvestigatorExportActivityParams{})\nif err != nil {\n\tlog.Fatal(err)\n}\ndefer resp.Body.Close()\nfile, err := os.Create(\"download.csv\")\nif err != nil {\n\tlog.Fatal(err)\n}\ndefer file.Close()\nif _, err := io.Copy(file, resp.Body); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.nio.file.Path;\nimport me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nclient.investigator().exportActivity()\n        .writeTo(Path.of(\"download.csv\"));"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$content = $didit->investigator->exportActivity();\n$content->saveTo('download.csv');"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ncontent = didit.investigator.export_activity\nFile.binwrite(\"download.csv\", content)"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar content = await client.Investigator.ExportActivityAsync();\nawait content.SaveToAsync(\"download.csv\");"
          }
        ]
      }
    },
    "/v3/investigator/settings/": {
      "get": {
        "operationId": "investigator_settings_retrieve",
        "summary": "Dapatkan pengaturan Investigator",
        "description": "Tahapan (`none`, `shadow`, atau `live`) dan batas pengeluaran bulanan beserta pengeluaran bulan ini. Kunci terbatas memerlukan cakupan `applications` (baca).",
        "tags": [
          "Investigator"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InvestigatorSettings"
                }
              }
            }
          },
          "401": {
            "description": "Kunci API tidak ada atau tidak valid."
          },
          "403": {
            "description": "Kunci tidak memiliki cakupan, jenis item tidak dapat dibaca, atau paket tidak mencakup Investigator."
          }
        },
        "x-didit-sdk": {
          "resource": "investigator",
          "method": "retrieve_settings",
          "auth": "api_key",
          "server": true
        },
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.investigator.retrieve_settings()\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.investigator.retrieveSettings();\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Investigator.RetrieveSettings(ctx)\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.investigator().retrieveSettings();\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->investigator->retrieveSettings();\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.investigator.retrieve_settings\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Investigator.RetrieveSettingsAsync();\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      },
      "patch": {
        "operationId": "investigator_settings_update",
        "summary": "Perbarui pengaturan Investigator",
        "description": "Ubah tahap, batas pengeluaran bulanan, atau keduanya. Berpindah melewati `none` membutuhkan paket yang mencakup Investigator (Growth atau lebih tinggi); `live` juga membutuhkan kontrak yang memuat harganya, jika Anda memilikinya. Kunci terbatas membutuhkan cakupan `applications` (write).",
        "tags": [
          "Investigator"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InvestigatorSettings"
                }
              }
            }
          },
          "400": {
            "description": "Tidak ada kolom yang dikirimkan, atau nilainya tidak valid."
          },
          "401": {
            "description": "Kunci API tidak ada atau tidak valid."
          },
          "403": {
            "description": "Kunci tidak memiliki cakupan, jenis item tidak dapat dibaca, atau paket tidak mencakup Investigator."
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/InvestigatorSettings"
              },
              "example": {
                "stage": "shadow",
                "monthly_spend_limit": "500.00"
              }
            }
          }
        },
        "x-didit-sdk": {
          "resource": "investigator",
          "method": "update_settings",
          "auth": "api_key",
          "server": true
        },
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.investigator.update_settings(\n    stage=\"shadow\",\n    monthly_spend_limit=\"500.00\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.investigator.updateSettings({\n  stage: \"shadow\",\n  monthly_spend_limit: \"500.00\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Investigator.UpdateSettings(ctx, didit.InvestigatorSettingsParam{\n\tStage:             didit.Some(didit.InvestigatorSettingsStage(\"shadow\")),\n\tMonthlySpendLimit: didit.String(\"500.00\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.InvestigatorSettings;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.investigator().updateSettings(InvestigatorSettings.builder()\n        .stage(InvestigatorSettings.Stage.of(\"shadow\"))\n        .monthlySpendLimit(\"500.00\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->investigator->updateSettings([\n    'stage' => 'shadow',\n    'monthly_spend_limit' => '500.00',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.investigator.update_settings(\n  stage: \"shadow\",\n  monthly_spend_limit: \"500.00\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Investigator.UpdateSettingsAsync(new InvestigatorSettings\n{\n    Stage = new InvestigatorSettingsStage(\"shadow\"),\n    MonthlySpendLimit = \"500.00\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/travel-rule/wallet-addresses/import/": {
      "post": {
        "summary": "Impor alamat dompet secara massal",
        "description": "Tambahkan hingga 10,000 dompet ke buku alamat Travel Rule Anda dalam satu panggilan, sebagai JSON atau file CSV. Dompet dapat dikirim berdasarkan alamatnya, berdasarkan SHA-256 dari alamatnya yang diubah ke huruf kecil (`address_hash`) untuk menjaga privasi alamat, atau keduanya. Impor bersifat idempoten: dompet yang sudah ada di buku dilaporkan sebagai `existing` dan dibiarkan apa adanya, sehingga file yang sama dapat dikirim lagi. Setiap baris divalidasi secara terpisah, sehingga satu baris yang buruk tidak akan pernah menggagalkan baris lainnya. Dompet yang diimpor berdasarkan hash-nya hanya cocok dengan transfer ke alamat tersebut dan dapat dibuktikan dengan widget kepemilikan dompet seperti entri lainnya.",
        "operationId": "importTravelRuleWalletAddresses",
        "tags": [
          "Travel Rule"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-didit-sdk": {
          "resource": "travel_rule.wallet_addresses",
          "method": "bulk_import",
          "auth": "api_key",
          "server": true
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "oneOf": [
                  {
                    "type": "object",
                    "required": [
                      "entries"
                    ],
                    "properties": {
                      "entries": {
                        "type": "array",
                        "minItems": 1,
                        "maxItems": 10000,
                        "items": {
                          "$ref": "#/components/schemas/WalletAddressImportRow"
                        }
                      }
                    }
                  },
                  {
                    "type": "array",
                    "minItems": 1,
                    "maxItems": 10000,
                    "items": {
                      "$ref": "#/components/schemas/WalletAddressImportRow"
                    }
                  }
                ]
              },
              "example": {
                "entries": [
                  {
                    "address": "0xBeneficiaryWallet01",
                    "chain": "ETH",
                    "holder_name": "Ana Diaz",
                    "holder_vendor_data": "user-042"
                  },
                  {
                    "address_hash": "4f7d2e1c9b8a7f6e5d4c3b2a1f0e9d8c7b6a5f4e3d2c1b0a9f8e7d6c5b4a3f2e",
                    "chain": "bitcoin",
                    "holder_vendor_data": "user-043"
                  },
                  {
                    "address": "rExchangeSharedAddress01",
                    "chain": "XRP",
                    "memo": "104729",
                    "holder_name": "Ana Diaz"
                  }
                ]
              }
            },
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "required": [
                  "file"
                ],
                "properties": {
                  "file": {
                    "type": "string",
                    "format": "binary",
                    "description": "File CSV UTF-8 maksimal 5 MB dengan baris header yang menyebutkan nama kolomnya (kolom pada baris tersebut atau aliasnya). Sel kosong dihitung sebagai tidak dikirim; kolom yang tidak dibaca oleh impor akan diabaikan."
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl (JSON)",
            "source": "curl -X POST https://verification.didit.me/v3/travel-rule/wallet-addresses/import/ \\\n  -H 'x-api-key: YOUR_API_KEY' -H 'Content-Type: application/json' \\\n  -d '{\"entries\": [{\"address\": \"0xBeneficiaryWallet01\", \"chain\": \"ETH\", \"holder_name\": \"Ana Diaz\"}, {\"address\": \"rExchangeSharedAddress01\", \"chain\": \"XRP\", \"memo\": \"104729\"}]}'"
          },
          {
            "lang": "curl",
            "label": "curl (CSV)",
            "source": "curl -X POST https://verification.didit.me/v3/travel-rule/wallet-addresses/import/ \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -F 'file=@wallets.csv;type=text/csv'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.travel_rule.wallet_addresses.bulk_import(\n    body={\n        \"entries\": [{\n            \"address\": \"0xBeneficiaryWallet01\",\n            \"chain\": \"ETH\",\n            \"holder_name\": \"Ana Diaz\",\n            \"holder_vendor_data\": \"user-042\",\n        }, {\n            \"address_hash\": \"4f7d2e1c9b8a7f6e5d4c3b2a1f0e9d8c7b6a5f4e3d2c1b0a9f8e7d6c5b4a3f2e\",\n            \"chain\": \"bitcoin\",\n            \"holder_vendor_data\": \"user-043\",\n        }, {\n            \"address\": \"rExchangeSharedAddress01\",\n            \"chain\": \"XRP\",\n            \"memo\": \"104729\",\n            \"holder_name\": \"Ana Diaz\",\n        }],\n    },\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit, { fileFromPath } from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.travelRule.walletAddresses.bulkImport({\n  file: await fileFromPath(\"wallet-addresses.csv\"),\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.TravelRule.WalletAddresses.BulkImport(ctx, didit.TravelRuleWalletAddressesBulkImportParams{\n\tFile: didit.Some(didit.FileFromPath(\"wallet-addresses.csv\")),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.nio.file.Path;\nimport me.didit.Didit;\nimport me.didit.types.TravelRuleWalletAddressesBulkImportParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.travelRule().walletAddresses().bulkImport(TravelRuleWalletAddressesBulkImportParams.builder()\n        .file(Path.of(\"wallet-addresses.csv\"))\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\nuse Didit\\File;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->travelRule->walletAddresses->bulkImport([\n    'file' => File::fromPath('wallet-addresses.csv'),\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.travel_rule.wallet_addresses.bulk_import(\n  body: {\n    entries: [{\n      address: \"0xBeneficiaryWallet01\",\n      chain: \"ETH\",\n      holder_name: \"Ana Diaz\",\n      holder_vendor_data: \"user-042\",\n    }, {\n      address_hash: \"4f7d2e1c9b8a7f6e5d4c3b2a1f0e9d8c7b6a5f4e3d2c1b0a9f8e7d6c5b4a3f2e\",\n      chain: \"bitcoin\",\n      holder_vendor_data: \"user-043\",\n    }, {\n      address: \"rExchangeSharedAddress01\",\n      chain: \"XRP\",\n      memo: \"104729\",\n      holder_name: \"Ana Diaz\",\n    }],\n  }\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.TravelRule.WalletAddresses.BulkImportAsync(new TravelRuleWalletAddressesBulkImportParams\n{\n    File = FileUpload.FromPath(\"wallet-addresses.csv\"),\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "Setiap baris dibuat, sudah ada di buku, atau merupakan pengulangan dari baris sebelumnya.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WalletAddressImportReport"
                },
                "example": {
                  "total": 3,
                  "created": 2,
                  "existing": 1,
                  "duplicate": 0,
                  "failed": 0,
                  "rows": [
                    {
                      "row": 1,
                      "status": "existing",
                      "entry_id": "11111111-2222-3333-4444-555555555555",
                      "errors": {},
                      "duplicate_of_row": null
                    },
                    {
                      "row": 2,
                      "status": "created",
                      "entry_id": "22222222-3333-4444-5555-666666666666",
                      "errors": {},
                      "duplicate_of_row": null
                    },
                    {
                      "row": 3,
                      "status": "created",
                      "entry_id": "33333333-4444-5555-6666-777777777777",
                      "errors": {},
                      "duplicate_of_row": null
                    }
                  ]
                }
              }
            }
          },
          "207": {
            "description": "Setidaknya satu baris gagal; baris lainnya berhasil diimpor. Setiap baris yang gagal mencantumkan kesalahannya.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WalletAddressImportReport"
                },
                "example": {
                  "total": 2,
                  "created": 1,
                  "existing": 0,
                  "duplicate": 0,
                  "failed": 1,
                  "rows": [
                    {
                      "row": 1,
                      "status": "created",
                      "entry_id": "44444444-5555-6666-7777-888888888888",
                      "errors": {},
                      "duplicate_of_row": null
                    },
                    {
                      "row": 2,
                      "status": "failed",
                      "entry_id": null,
                      "errors": {
                        "address": [
                          "Send address, address_hash or both."
                        ]
                      },
                      "duplicate_of_row": null
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Permintaan itu sendiri tidak dapat dibaca: menyertakan `entries` dan `file` sekaligus, atau tidak menyertakan keduanya; lebih dari 10,000 baris; file berukuran lebih dari 5 MB, bukan CSV UTF-8, tanpa baris header, atau tanpa baris.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "file": [
                    "At most 10000 rows per import."
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/v3/travel-rule/counterparty-contacts/": {
      "get": {
        "summary": "Daftar kontak pihak lawan",
        "description": "Alamat kepatuhan yang dapat dikirimi email oleh jalur EMAIL untuk aplikasi Anda: kontak platform Didit ditambah kontak privat milik aplikasi Anda sendiri, termasuk yang gagal terkirim, yang terbaru terlebih dahulu. Diberi nomor halaman dengan `limit` (default 50) dan `offset`; `count` berhenti di 100, sehingga 100 berarti 100 atau lebih.",
        "operationId": "listTravelRuleCounterpartyContacts",
        "x-didit-sdk": {
          "resource": "travel_rule.counterparty_contacts",
          "method": "list",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Travel Rule"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "counterparty",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Hanya kontak dari entri direktori ini. Harus berupa UUID; nilai kosong berarti tanpa filter."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1
            },
            "description": "Ukuran halaman, nilai default-nya 50."
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 0
            },
            "description": "Baris yang akan dilewati."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/travel-rule/counterparty-contacts/?counterparty={vasp_id}' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nfor item in client.travel_rule.counterparty_contacts.list():\n    print(item)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nfor await (const item of didit.travelRule.counterpartyContacts.list()) {\n  console.log(item);\n}"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\niter := client.TravelRule.CounterpartyContacts.ListAutoPaging(ctx, didit.TravelRuleCounterpartyContactsListParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nfor (var item : client.travelRule().counterpartyContacts().list()) {\n    System.out.println(item);\n}"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\nforeach ($didit->travelRule->counterpartyContacts->list() as $item) {\n    print_r($item->toArray());\n}"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.travel_rule.counterparty_contacts.list.auto_paging_each do |item|\n  puts item.to_h\nend"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.TravelRule.CounterpartyContacts.ListAsync())\n{\n    Console.WriteLine(JsonSerializer.Serialize(item));\n}"
          }
        ],
        "responses": {
          "200": {
            "description": "Kontak.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "count": {
                      "type": "integer"
                    },
                    "next": {
                      "type": "string",
                      "nullable": true
                    },
                    "previous": {
                      "type": "string",
                      "nullable": true
                    },
                    "results": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/TravelRuleCounterpartyContact"
                      }
                    }
                  }
                },
                "example": {
                  "count": 1,
                  "next": null,
                  "previous": null,
                  "results": [
                    {
                      "uuid": "6c1f9b8e-2d4a-4f7e-8b3c-5a9d0e1f2a3b",
                      "counterparty": "0d6f3c2a-6a1e-4c55-9a39-1f2b0c7d8e91",
                      "counterparty_name": "Example Counterparty VASP",
                      "email": "compliance@counterparty.example",
                      "name": "Compliance desk",
                      "source": "application",
                      "scope": "application",
                      "created_by": "",
                      "verified_at": null,
                      "is_invalid": false,
                      "invalid_reason": "",
                      "invalid_detail": "",
                      "invalid_at": null,
                      "created_at": "2026-10-19T09:00:00Z"
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "`counterparty` bukan sebuah UUID.",
            "content": {
              "application/json": {
                "example": {
                  "counterparty": [
                    "Must be a valid UUID."
                  ]
                }
              }
            }
          }
        }
      },
      "post": {
        "summary": "Tambahkan kontak pihak lawan",
        "description": "Menambahkan alamat kepatuhan privat untuk satu entri direktori. Hanya aplikasi Anda yang melihat dan menggunakannya, dan rel EMAIL menulis ke alamat tersebut sebelum kontak platform apa pun. Menambahkan alamat yang sudah dimiliki entri tersebut di antara kontak Anda sendiri akan mengembalikan kontak tersebut.",
        "operationId": "createTravelRuleCounterpartyContact",
        "x-didit-sdk": {
          "resource": "travel_rule.counterparty_contacts",
          "method": "create",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Travel Rule"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TravelRuleCounterpartyContactCreate"
              },
              "example": {
                "counterparty": "0d6f3c2a-6a1e-4c55-9a39-1f2b0c7d8e91",
                "email": "compliance@counterparty.example",
                "name": "Compliance desk"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST https://verification.didit.me/v3/travel-rule/counterparty-contacts/ \\\n  -H 'x-api-key: YOUR_API_KEY' -H 'Content-Type: application/json' \\\n  -d '{\"counterparty\": \"0d6f3c2a-6a1e-4c55-9a39-1f2b0c7d8e91\", \"email\": \"compliance@counterparty.example\", \"name\": \"Compliance desk\"}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.travel_rule.counterparty_contacts.create(\n    counterparty=\"0d6f3c2a-6a1e-4c55-9a39-1f2b0c7d8e91\",\n    email=\"compliance@counterparty.example\",\n    name=\"Compliance desk\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.travelRule.counterpartyContacts.create({\n  counterparty: \"0d6f3c2a-6a1e-4c55-9a39-1f2b0c7d8e91\",\n  email: \"compliance@counterparty.example\",\n  name: \"Compliance desk\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.TravelRule.CounterpartyContacts.Create(ctx, didit.TravelRuleCounterpartyContactCreate{\n\tCounterparty: \"0d6f3c2a-6a1e-4c55-9a39-1f2b0c7d8e91\",\n\tEmail:        \"compliance@counterparty.example\",\n\tName:         didit.String(\"Compliance desk\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.TravelRuleCounterpartyContactCreate;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.travelRule().counterpartyContacts().create(TravelRuleCounterpartyContactCreate.builder()\n        .counterparty(\"0d6f3c2a-6a1e-4c55-9a39-1f2b0c7d8e91\")\n        .email(\"compliance@counterparty.example\")\n        .name(\"Compliance desk\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->travelRule->counterpartyContacts->create([\n    'counterparty' => '0d6f3c2a-6a1e-4c55-9a39-1f2b0c7d8e91',\n    'email' => 'compliance@counterparty.example',\n    'name' => 'Compliance desk',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.travel_rule.counterparty_contacts.create(\n  counterparty: \"0d6f3c2a-6a1e-4c55-9a39-1f2b0c7d8e91\",\n  email: \"compliance@counterparty.example\",\n  name: \"Compliance desk\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.TravelRule.CounterpartyContacts.CreateAsync(new TravelRuleCounterpartyContactCreate\n{\n    Counterparty = \"0d6f3c2a-6a1e-4c55-9a39-1f2b0c7d8e91\",\n    Email = \"compliance@counterparty.example\",\n    Name = \"Compliance desk\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "201": {
            "description": "Kontak telah ditambahkan.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TravelRuleCounterpartyContact"
                },
                "example": {
                  "uuid": "6c1f9b8e-2d4a-4f7e-8b3c-5a9d0e1f2a3b",
                  "counterparty": "0d6f3c2a-6a1e-4c55-9a39-1f2b0c7d8e91",
                  "counterparty_name": "Example Counterparty VASP",
                  "email": "compliance@counterparty.example",
                  "name": "Compliance desk",
                  "source": "application",
                  "scope": "application",
                  "created_by": "",
                  "verified_at": null,
                  "is_invalid": false,
                  "invalid_reason": "",
                  "invalid_detail": "",
                  "invalid_at": null,
                  "created_at": "2026-10-19T09:00:00Z"
                }
              }
            }
          },
          "400": {
            "description": "Kolom tidak ada atau tidak valid, atau tidak ada entri direktori yang memiliki id ini.",
            "content": {
              "application/json": {
                "example": {
                  "counterparty": [
                    "No directory entry with this id."
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/v3/travel-rule/counterparty-contacts/{contact_uuid}/": {
      "delete": {
        "summary": "Hapus kontak pihak lawan",
        "description": "Menghapus salah satu kontak milik aplikasi Anda. Jalur EMAIL segera berhenti menulis kepadanya. Kontak platform tidak dapat dihapus.",
        "operationId": "deleteTravelRuleCounterpartyContact",
        "x-didit-sdk": {
          "resource": "travel_rule.counterparty_contacts",
          "method": "delete",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Travel Rule"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "contact_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X DELETE https://verification.didit.me/v3/travel-rule/counterparty-contacts/{contact_uuid}/ \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nclient.travel_rule.counterparty_contacts.delete(\n    \"11111111-2222-3333-4444-555555555555\",\n)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nawait didit.travelRule.counterpartyContacts.delete(\"11111111-2222-3333-4444-555555555555\");"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nif err := client.TravelRule.CounterpartyContacts.Delete(ctx, \"11111111-2222-3333-4444-555555555555\"); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nclient.travelRule().counterpartyContacts().delete(\"11111111-2222-3333-4444-555555555555\");"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$didit->travelRule->counterpartyContacts->delete('11111111-2222-3333-4444-555555555555');"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.travel_rule.counterparty_contacts.delete(\"11111111-2222-3333-4444-555555555555\")"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nawait client.TravelRule.CounterpartyContacts.DeleteAsync(\"11111111-2222-3333-4444-555555555555\");"
          }
        ],
        "responses": {
          "204": {
            "description": "Dihapus."
          },
          "404": {
            "description": "Tidak ada kontak dari aplikasi Anda yang memiliki id ini. Kontak platform juga mengembalikan 404."
          }
        }
      }
    },
    "/v3/travel-rule/transfers/": {
      "get": {
        "summary": "Daftar transfer Travel Rule",
        "description": "Transfer Travel Rule aplikasi Anda, yang terbaru lebih dahulu, diberi penomoran halaman dengan `limit` (default 50) dan `offset`. Baris hanya memuat nama VASP, dompet, dan memo, tidak pernah data individu. Nilai yang dipisahkan koma memilih beberapa. Nilai yang tidak dikenal menghasilkan respons 400 yang menyebutkan parameternya, misalnya `{\"direction\": [\"Unknown value(s): inbound.\"]}`.",
        "operationId": "listTravelRuleTransfers",
        "x-didit-sdk": {
          "resource": "travel_rule.transfers",
          "method": "list",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Travel Rule"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "direction",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "INBOUND, OUTBOUND, atau keduanya dipisahkan koma. Peka huruf besar/kecil."
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Satu atau lebih status transfer, dipisahkan koma."
          },
          {
            "name": "rail",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Satu atau lebih dari INTERNAL, TRP, GTR, TRUST, VERIFYVASP, SYGNA, EMAIL, TEST_VASP, dipisahkan koma."
          },
          {
            "name": "kind",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "withdrawal, deposit, atau message, dipisahkan koma."
          },
          {
            "name": "currency",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Mata uang transaksi, tidak peka huruf besar/kecil."
          },
          {
            "name": "start_date",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date"
            },
            "description": "Transfer yang dibuat pada atau setelah tanggal ini (UTC), YYYY-MM-DD."
          },
          {
            "name": "end_date",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date"
            },
            "description": "Transfer yang dibuat pada atau sebelum tanggal ini (UTC), YYYY-MM-DD."
          },
          {
            "name": "counterparty",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "`id` entri direktori atau anggota jaringan Didit dari GET /v3/travel-rule/vasps/: transfer Anda dengan pihak lawan tersebut. Nilai yang bukan id yang valid menghasilkan 400."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1
            },
            "description": "Ukuran halaman, nilai default-nya 50."
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 0
            },
            "description": "Baris yang akan dilewati."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/travel-rule/transfers/?direction=OUTBOUND&status=AWAITING_COUNTERPARTY' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nfor item in client.travel_rule.transfers.list():\n    print(item)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nfor await (const item of didit.travelRule.transfers.list()) {\n  console.log(item);\n}"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\niter := client.TravelRule.Transfers.ListAutoPaging(ctx, didit.TravelRuleTransfersListParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nfor (var item : client.travelRule().transfers().list()) {\n    System.out.println(item);\n}"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\nforeach ($didit->travelRule->transfers->list() as $item) {\n    print_r($item->toArray());\n}"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.travel_rule.transfers.list.auto_paging_each do |item|\n  puts item.to_h\nend"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.TravelRule.Transfers.ListAsync())\n{\n    Console.WriteLine(JsonSerializer.Serialize(item));\n}"
          }
        ],
        "responses": {
          "200": {
            "description": "Satu halaman transfer.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "count": {
                      "type": "integer"
                    },
                    "next": {
                      "type": "string",
                      "nullable": true
                    },
                    "previous": {
                      "type": "string",
                      "nullable": true
                    },
                    "results": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/TravelRuleTransferRow"
                      }
                    }
                  }
                },
                "example": {
                  "count": 1,
                  "next": null,
                  "previous": null,
                  "results": [
                    {
                      "id": "5b0f6c2e-2a4d-4f0e-9a41-0c3f9a7e1d22",
                      "transaction_id": "a3c1e8f4-7b62-4d1a-8e0b-2f9d6c4b7a10",
                      "txn_id": "wd-2026-10-19-0042",
                      "txn_date": "2026-10-19T08:41:12Z",
                      "kind": "withdrawal",
                      "direction": "OUTBOUND",
                      "status": "AWAITING_COUNTERPARTY",
                      "rail": "TRP",
                      "asset": "ETH",
                      "amount": "1.25",
                      "originator_vasp": "Origin CASP SL",
                      "beneficiary_vasp": "Example Counterparty VASP",
                      "originator_wallet": "0x77ccff0cc624a53cd8b8d8703ced826710211ec7",
                      "beneficiary_wallet": "0xede2d7e4f5b097e6391ab6bbcf2f47a53f4778cb",
                      "originator_memo": "",
                      "beneficiary_memo": "",
                      "originator_wallet_type": "vasp",
                      "beneficiary_wallet_type": "vasp",
                      "matched_transaction_id": null,
                      "deadline_at": "2026-10-21T08:41:13Z",
                      "created_at": "2026-10-19T08:41:13Z"
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Nilai filter tidak valid.",
            "content": {
              "application/json": {
                "example": {
                  "start_date": [
                    "Use the YYYY-MM-DD format."
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/v3/session/imports/providers/": {
      "get": {
        "summary": "Mencantumkan penyedia migrasi",
        "description": "15 penyedia tempat Anda dapat memigrasikan verifikasi: apa yang dibutuhkan masing-masing penyedia untuk terhubung, apakah API-nya dapat menampilkan daftar rekaman, izin yang dibutuhkan kuncinya, dan pemetaan status default-nya.",
        "operationId": "get_v3_session_imports_providers_list",
        "x-didit-sdk": {
          "resource": "sessions.imports",
          "method": "list_providers",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Sessions"
        ],
        "responses": {
          "200": {
            "description": "Penyedia migrasi.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "providers": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/ImportProvider"
                      }
                    },
                    "mapping_targets": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "skipped_statuses": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Kunci API tidak ada, tidak valid, atau dicabut, atau pemanggil tidak dapat mengimpor verifikasi untuk aplikasi ini.",
            "content": {
              "application/json": {
                "examples": {
                  "Forbidden": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.imports.list_providers()\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.imports.listProviders();\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.Imports.ListProviders(ctx)\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().imports().listProviders();\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->sessions->imports->listProviders();\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.imports.list_providers\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.Imports.ListProvidersAsync();\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/session/imports/providers/check/": {
      "post": {
        "summary": "Periksa kunci penyedia",
        "description": "Baca penyedia dengan kunci Anda sebelum membuat migrasi. Tidak ada yang disimpan.",
        "operationId": "post_v3_session_imports_providers_check",
        "x-didit-sdk": {
          "resource": "sessions.imports",
          "method": "check_provider",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Sessions"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "provider": {
                    "type": "string",
                    "enum": [
                      "sumsub",
                      "jumio",
                      "veriff",
                      "onfido",
                      "persona",
                      "metamap",
                      "socure",
                      "idnow",
                      "shufti",
                      "idenfy",
                      "ondato",
                      "trulioo",
                      "au10tix",
                      "complycube",
                      "other"
                    ],
                    "description": "Sumber migrasi, dari `GET /v3/session/imports/providers/`. Wajib diisi jika `source` adalah `provider`."
                  },
                  "credentials": {
                    "type": "object",
                    "additionalProperties": {
                      "type": "string"
                    },
                    "description": "Kunci hanya-baca penyedia, dengan nama kolom yang tercantum dalam `credential_fields`. Dienkripsi saat disimpan, tidak pernah dikembalikan, dan dihapus saat impor selesai. Kirim sebagai string JSON dalam multipart."
                  },
                  "options": {
                    "type": "object",
                    "properties": {
                      "region": {
                        "type": "string",
                        "description": "Wilayah penyedia, salah satu dari `regions` miliknya (Onfido: `eu`, `us`, `ca`)."
                      }
                    }
                  },
                  "record_ids": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Untuk penyedia `api_ids`: ID rekaman pertama dari ekspor Anda."
                  }
                },
                "required": [
                  "provider",
                  "credentials"
                ]
              },
              "example": {
                "provider": "sumsub",
                "credentials": {
                  "app_token": "YOUR_PROVIDER_APP_TOKEN",
                  "secret_key": "YOUR_PROVIDER_SECRET_KEY"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Kunci dapat membaca rekaman.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "provider": {
                      "type": "string"
                    },
                    "credential_hint": {
                      "type": "string",
                      "nullable": true
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Penyedia menolak kunci: `code`, `detail`, `missing_permissions`, `suggested_region`."
          },
          "403": {
            "description": "Kunci API tidak ada, tidak valid, atau dicabut, atau pemanggil tidak dapat mengimpor verifikasi untuk aplikasi ini.",
            "content": {
              "application/json": {
                "examples": {
                  "Forbidden": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.imports.check_provider(\n    provider=\"sumsub\",\n    credentials={\"app_token\": \"YOUR_PROVIDER_APP_TOKEN\", \"secret_key\": \"YOUR_PROVIDER_SECRET_KEY\"},\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.imports.checkProvider({\n  provider: \"sumsub\",\n  credentials: { app_token: \"YOUR_PROVIDER_APP_TOKEN\", secret_key: \"YOUR_PROVIDER_SECRET_KEY\" },\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.Imports.CheckProvider(ctx, didit.SessionsImportsCheckProviderParams{\n\tProvider:    \"sumsub\",\n\tCredentials: map[string]string{\"app_token\": \"YOUR_PROVIDER_APP_TOKEN\", \"secret_key\": \"YOUR_PROVIDER_SECRET_KEY\"},\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.SessionsImportsCheckProviderParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().imports().checkProvider(SessionsImportsCheckProviderParams.builder()\n        .provider(SessionsImportsCheckProviderParams.Provider.of(\"sumsub\"))\n        .credentials(Map.of(\"app_token\", \"YOUR_PROVIDER_APP_TOKEN\", \"secret_key\", \"YOUR_PROVIDER_SECRET_KEY\"))\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->sessions->imports->checkProvider([\n    'provider' => 'sumsub',\n    'credentials' => ['app_token' => 'YOUR_PROVIDER_APP_TOKEN', 'secret_key' => 'YOUR_PROVIDER_SECRET_KEY'],\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.imports.check_provider(\n  provider: \"sumsub\",\n  credentials: { app_token: \"YOUR_PROVIDER_APP_TOKEN\", secret_key: \"YOUR_PROVIDER_SECRET_KEY\" }\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.Imports.CheckProviderAsync(new SessionsImportsCheckProviderParams\n{\n    Provider = \"sumsub\",\n    Credentials = new Dictionary<string, string> { [\"app_token\"] = \"YOUR_PROVIDER_APP_TOKEN\", [\"secret_key\"] = \"YOUR_PROVIDER_SECRET_KEY\" },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/session/imports/{importId}/start/": {
      "post": {
        "summary": "Mulai uji coba",
        "description": "Mulai migrasi yang dry run-nya telah selesai (`READY`): job yang sama melakukan impor sesungguhnya, dengan pemetaan status dan pilihan templat wajah seperti yang dikirim sekarang.",
        "operationId": "post_v3_session_imports_start",
        "x-didit-sdk": {
          "resource": "sessions.imports",
          "method": "start",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Sessions"
        ],
        "parameters": [
          {
            "name": "importId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "status_mapping": {
                    "type": "object",
                    "additionalProperties": {
                      "type": "string",
                      "enum": [
                        "Approved",
                        "Declined",
                        "In Review",
                        "Expired",
                        "Not Finished",
                        "Abandoned"
                      ]
                    },
                    "description": "Pengeditan pada pemetaan status default penyedia: status sumber ke status Didit. `Not Finished` dan `Abandoned` dilewati dan dihitung, tidak pernah diimpor."
                  },
                  "face_templates": {
                    "type": "boolean",
                    "default": false,
                    "description": "Buat templat wajah dari swafoto yang diimpor dan cari terhadap wajah serta daftar blokir aplikasi. Kecocokan hanya ditandai untuk ditinjau. Memerlukan `lawful_basis_confirmed`."
                  },
                  "lawful_basis_confirmed": {
                    "type": "boolean",
                    "default": false,
                    "description": "Mengonfirmasi bahwa Anda memiliki dasar hukum untuk membagikan swafoto ini kepada Didit sebagai pemroses."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Tugas impor.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SessionImportJob"
                }
              }
            }
          },
          "400": {
            "description": "Tugas tidak berada dalam status yang sesuai untuk tindakan ini."
          },
          "403": {
            "description": "Kunci API tidak ada, tidak valid, atau dicabut, atau pemanggil tidak dapat mengimpor verifikasi untuk aplikasi ini.",
            "content": {
              "application/json": {
                "examples": {
                  "Forbidden": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.imports.start(\n    \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.imports.start(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.Imports.Start(ctx, \"11111111-2222-3333-4444-555555555555\", didit.SessionsImportsStartParams{})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().imports().start(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->sessions->imports->start('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.imports.start(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.Imports.StartAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/session/imports/{importId}/pause/": {
      "post": {
        "summary": "Jeda tugas impor",
        "description": "Jeda impor yang sedang dalam antrean atau sedang berjalan.",
        "operationId": "post_v3_session_imports_pause",
        "x-didit-sdk": {
          "resource": "sessions.imports",
          "method": "pause",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Sessions"
        ],
        "parameters": [
          {
            "name": "importId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Tugas impor.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SessionImportJob"
                }
              }
            }
          },
          "400": {
            "description": "Tugas tidak berada dalam status yang sesuai untuk tindakan ini."
          },
          "403": {
            "description": "Kunci API tidak ada, tidak valid, atau dicabut, atau pemanggil tidak dapat mengimpor verifikasi untuk aplikasi ini.",
            "content": {
              "application/json": {
                "examples": {
                  "Forbidden": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.imports.pause(\n    \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.imports.pause(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.Imports.Pause(ctx, \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().imports().pause(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->sessions->imports->pause('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.imports.pause(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.Imports.PauseAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/session/imports/{importId}/resume/": {
      "post": {
        "summary": "Lanjutkan pekerjaan impor",
        "description": "Lanjutkan impor yang Anda jeda. Pekerjaan yang dijeda oleh batas laju penyedia akan dilanjutkan dengan sendirinya.",
        "operationId": "post_v3_session_imports_resume",
        "x-didit-sdk": {
          "resource": "sessions.imports",
          "method": "resume",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Sessions"
        ],
        "parameters": [
          {
            "name": "importId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Tugas impor.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SessionImportJob"
                }
              }
            }
          },
          "400": {
            "description": "Tugas tidak berada dalam status yang sesuai untuk tindakan ini."
          },
          "403": {
            "description": "Kunci API tidak ada, tidak valid, atau dicabut, atau pemanggil tidak dapat mengimpor verifikasi untuk aplikasi ini.",
            "content": {
              "application/json": {
                "examples": {
                  "Forbidden": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.imports.resume(\n    \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.imports.resume(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.Imports.Resume(ctx, \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().imports().resume(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->sessions->imports->resume('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.imports.resume(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.Imports.ResumeAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/session/imports/{importId}/cancel/": {
      "post": {
        "summary": "Batalkan tugas impor",
        "description": "Batalkan impor. Data yang sudah diimpor tetap tersimpan; file yang diunggah dan kunci akan dihapus.",
        "operationId": "post_v3_session_imports_cancel",
        "x-didit-sdk": {
          "resource": "sessions.imports",
          "method": "cancel",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Sessions"
        ],
        "parameters": [
          {
            "name": "importId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Tugas impor.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SessionImportJob"
                }
              }
            }
          },
          "400": {
            "description": "Tugas tidak berada dalam status yang sesuai untuk tindakan ini."
          },
          "403": {
            "description": "Kunci API tidak ada, tidak valid, atau dicabut, atau pemanggil tidak dapat mengimpor verifikasi untuk aplikasi ini.",
            "content": {
              "application/json": {
                "examples": {
                  "Forbidden": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.imports.cancel(\n    \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.imports.cancel(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.Imports.Cancel(ctx, \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().imports().cancel(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->sessions->imports->cancel('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.imports.cancel(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.Imports.CancelAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/session/imports/{importId}/retry/": {
      "post": {
        "summary": "Coba lagi migrasi",
        "description": "Jalankan kembali migrasi yang telah berakhir sebagai tugas baru, dengan kunci baru (kunci lama telah dihapus). Tindakan ini mempertahankan penyedia, alur kerja, wilayah, pemetaan status, dan pilihan templat wajah; semua yang sudah ada di Didit akan dilewati.",
        "operationId": "post_v3_session_imports_retry",
        "x-didit-sdk": {
          "resource": "sessions.imports",
          "method": "retry",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Sessions"
        ],
        "parameters": [
          {
            "name": "importId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "properties": {
                  "credentials": {
                    "type": "object",
                    "additionalProperties": {
                      "type": "string"
                    },
                    "description": "Kunci hanya-baca penyedia, dengan nama kolom yang tercantum dalam `credential_fields`. Dienkripsi saat disimpan, tidak pernah dikembalikan, dan dihapus saat impor selesai. Kirim sebagai string JSON dalam multipart."
                  },
                  "file": {
                    "type": "string",
                    "format": "binary",
                    "description": "ID rekaman atau file ekspor sekali lagi, untuk penyedia `api_ids` dan `export_file`."
                  }
                }
              },
              "example": {
                "credentials": {
                  "app_token": "YOUR_PROVIDER_APP_TOKEN",
                  "secret_key": "YOUR_PROVIDER_SECRET_KEY"
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Pekerjaan impor baru.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SessionImportJob"
                }
              }
            }
          },
          "400": {
            "description": "Bukan migrasi, belum berakhir, atau penyedia menolak kunci tersebut."
          },
          "403": {
            "description": "Kunci API tidak ada, tidak valid, atau dicabut, atau pemanggil tidak dapat mengimpor verifikasi untuk aplikasi ini.",
            "content": {
              "application/json": {
                "examples": {
                  "Forbidden": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.imports.retry(\n    \"11111111-2222-3333-4444-555555555555\",\n    credentials={\"app_token\": \"YOUR_PROVIDER_APP_TOKEN\", \"secret_key\": \"YOUR_PROVIDER_SECRET_KEY\"},\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.imports.retry(\"11111111-2222-3333-4444-555555555555\", {\n  credentials: { app_token: \"YOUR_PROVIDER_APP_TOKEN\", secret_key: \"YOUR_PROVIDER_SECRET_KEY\" },\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.Imports.Retry(ctx, \"11111111-2222-3333-4444-555555555555\", didit.SessionsImportsRetryParams{\n\tCredentials: didit.Some(map[string]string{\"app_token\": \"YOUR_PROVIDER_APP_TOKEN\", \"secret_key\": \"YOUR_PROVIDER_SECRET_KEY\"}),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.Map;\nimport me.didit.Didit;\nimport me.didit.types.SessionsImportsRetryParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().imports().retry(\"11111111-2222-3333-4444-555555555555\", SessionsImportsRetryParams.builder()\n        .credentials(Map.of(\"app_token\", \"YOUR_PROVIDER_APP_TOKEN\", \"secret_key\", \"YOUR_PROVIDER_SECRET_KEY\"))\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->sessions->imports->retry('11111111-2222-3333-4444-555555555555', [\n    'credentials' => ['app_token' => 'YOUR_PROVIDER_APP_TOKEN', 'secret_key' => 'YOUR_PROVIDER_SECRET_KEY'],\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.imports.retry(\n  \"11111111-2222-3333-4444-555555555555\",\n  credentials: { app_token: \"YOUR_PROVIDER_APP_TOKEN\", secret_key: \"YOUR_PROVIDER_SECRET_KEY\" }\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.Imports.RetryAsync(\"11111111-2222-3333-4444-555555555555\", new SessionsImportsRetryParams\n{\n    Credentials = new Dictionary<string, string> { [\"app_token\"] = \"YOUR_PROVIDER_APP_TOKEN\", [\"secret_key\"] = \"YOUR_PROVIDER_SECRET_KEY\" },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/import-jobs/": {
      "get": {
        "summary": "Mencantumkan pekerjaan impor",
        "description": "Setiap impor dari aplikasi dalam satu bentuk: impor verifikasi dan migrasi, individu dan bisnis.",
        "operationId": "get_v3_import_jobs_list",
        "x-didit-sdk": {
          "resource": "sessions.imports",
          "method": "list_jobs",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Sessions"
        ],
        "parameters": [
          {
            "name": "scope",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "all",
                "sessions",
                "users",
                "businesses"
              ],
              "default": "all"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 50
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Pekerjaan impor, terbaru terlebih dahulu.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "results": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/ImportJobSummary"
                      }
                    },
                    "counts": {
                      "type": "object",
                      "properties": {
                        "all": {
                          "type": "integer"
                        },
                        "running_and_waiting": {
                          "type": "integer"
                        },
                        "needs_attention": {
                          "type": "integer"
                        },
                        "done": {
                          "type": "integer"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Kunci API tidak ada, tidak valid, atau dicabut, atau pemanggil tidak dapat mengimpor verifikasi untuk aplikasi ini.",
            "content": {
              "application/json": {
                "examples": {
                  "Forbidden": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.imports.list_jobs()\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.imports.listJobs();\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.Imports.ListJobs(ctx, didit.SessionsImportsListJobsParams{})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().imports().listJobs();\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->sessions->imports->listJobs();\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.imports.list_jobs\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.Imports.ListJobsAsync();\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/import-jobs/active/": {
      "get": {
        "summary": "Daftar pekerjaan impor yang aktif",
        "description": "Hal yang sedang berjalan atau menunggu, ditambah hal yang baru saja selesai, untuk indikator progres.",
        "operationId": "get_v3_import_jobs_active",
        "x-didit-sdk": {
          "resource": "sessions.imports",
          "method": "list_active_jobs",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Sessions"
        ],
        "responses": {
          "200": {
            "description": "Pekerjaan impor yang aktif.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "results": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/ImportJobSummary"
                      }
                    },
                    "running": {
                      "type": "integer"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Kunci API tidak ada, tidak valid, atau dicabut, atau pemanggil tidak dapat mengimpor verifikasi untuk aplikasi ini.",
            "content": {
              "application/json": {
                "examples": {
                  "Forbidden": {
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.imports.list_active_jobs()\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.imports.listActiveJobs();\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.Imports.ListActiveJobs(ctx)\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().imports().listActiveJobs();\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->sessions->imports->listActiveJobs();\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.imports.list_active_jobs\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.Imports.ListActiveJobsAsync();\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/organization/{organization_id}/application/{application_id}/transactions/delete/": {
      "delete": {
        "summary": "Hapus transaksi secara batch",
        "description": "Hapus satu atau beberapa transaksi secara permanen. Pilih transaksi tersebut dengan `transaction_uuids`, atau hapus setiap transaksi di aplikasi dengan `delete_all: true`.\n\nTransaksi yang dihapus akan terhapus bersama catatan yang hanya miliknya sendiri: pihak-pihaknya, tag, catatan, tautan metode pembayaran, dokumen dan setiap versi tersimpan dari filenya, eksekusi aturan, alert, hasil penyedia, snapshot jaringan, dan data Travel Rule. Kasus, orang, dan perusahaan tetap ada; tautannya ke transaksi yang dihapus akan dibersihkan. Draf laporan regulasi berhenti mencantumkannya dan dibuat ulang tanpanya. Penghapusan bersifat permanen dan tidak dapat dibatalkan; tidak ada endpoint undo.\n\nJika ada transaksi yang dipilih tercantum dalam laporan regulasi yang telah difinalisasi, seluruh permintaan ditolak dengan `409` dan tidak ada yang dihapus. Body respons menggunakan `code: in_filed_report` dan menyebutkan setiap transaksi serta laporan yang mencantumkannya. Hapus laporan-laporan tersebut, lalu ulangi permintaan.",
        "operationId": "batch_delete_transactions",
        "x-didit-sdk": {
          "resource": "transactions",
          "method": "batch_delete",
          "auth": "api_key",
          "server": true,
          "scope": "application"
        },
        "tags": [
          "Transactions"
        ],
        "parameters": [
          {
            "name": "organization_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID organisasi."
          },
          {
            "name": "application_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "UUID aplikasi."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "oneOf": [
                  {
                    "title": "Selected transactions",
                    "required": [
                      "transaction_uuids"
                    ],
                    "properties": {
                      "transaction_uuids": {
                        "type": "array",
                        "items": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "description": "UUID transaksi Didit yang akan dihapus. Wajib diisi kecuali `delete_all` bernilai true.",
                        "minItems": 1
                      },
                      "delete_all": {
                        "type": "boolean",
                        "enum": [
                          false
                        ],
                        "default": false,
                        "description": "Jangan sertakan atau kirim `false` saat Anda memilih transaksi dengan `transaction_uuids`."
                      }
                    }
                  },
                  {
                    "title": "All transactions",
                    "required": [
                      "delete_all"
                    ],
                    "properties": {
                      "delete_all": {
                        "type": "boolean",
                        "enum": [
                          true
                        ],
                        "description": "Hapus setiap transaksi di aplikasi. `transaction_uuids` diabaikan."
                      },
                      "transaction_uuids": {
                        "type": "array",
                        "items": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "description": "Diabaikan saat `delete_all` bernilai true."
                      }
                    }
                  }
                ]
              },
              "examples": {
                "Selected transactions": {
                  "value": {
                    "transaction_uuids": [
                      "abcdef12-3456-7890-abcd-ef1234567890",
                      "12345678-90ab-cdef-1234-567890abcdef"
                    ]
                  }
                },
                "All transactions": {
                  "value": {
                    "delete_all": true
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl (selected transactions)",
            "source": "curl -X DELETE 'https://verification.didit.me/v3/organization/11111111-2222-3333-4444-555555555555/application/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/transactions/delete/' \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"transaction_uuids\": [\"abcdef12-3456-7890-abcd-ef1234567890\"]}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\nclient = Didit()\n\nclient.transactions.batch_delete(\n    body={\n        \"transaction_uuids\": [\"abcdef12-3456-7890-abcd-ef1234567890\", \"12345678-90ab-cdef-1234-567890abcdef\"],\n    },\n)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nconst didit = new Didit();\n\nawait didit.transactions.batchDelete({\n  transaction_uuids: [\"abcdef12-3456-7890-abcd-ef1234567890\", \"12345678-90ab-cdef-1234-567890abcdef\"],\n});"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.util.List;\nimport me.didit.Didit;\nimport me.didit.types.TransactionsBatchDeleteParams;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nDidit client = new Didit();\n\nclient.transactions().batchDelete(TransactionsBatchDeleteParams.builder()\n        .putAdditionalProperty(\"transaction_uuids\", List.of(\"abcdef12-3456-7890-abcd-ef1234567890\", \"12345678-90ab-cdef-1234-567890abcdef\"))\n        .build());"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\n$didit = new DiditClient();\n\n$didit->transactions->batchDelete([\n    'transaction_uuids' => ['abcdef12-3456-7890-abcd-ef1234567890', '12345678-90ab-cdef-1234-567890abcdef'],\n]);"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n# and DIDIT_APPLICATION_ID.\ndidit = Didit::Client.new\n\ndidit.transactions.batch_delete(\n  body: {\n    transaction_uuids: [\"abcdef12-3456-7890-abcd-ef1234567890\", \"12345678-90ab-cdef-1234-567890abcdef\"],\n  }\n)"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing Didit;\n\n// Reads DIDIT_API_KEY, DIDIT_ORGANIZATION_ID\n// and DIDIT_APPLICATION_ID.\nusing var client = new DiditClient();\n\nawait client.Transactions.BatchDeleteAsync(new TransactionsBatchDeleteParams\n{\n    TransactionUuids = new string[] { \"abcdef12-3456-7890-abcd-ef1234567890\", \"12345678-90ab-cdef-1234-567890abcdef\" },\n});"
          }
        ],
        "responses": {
          "204": {
            "description": "Transaksi terpilih dihapus."
          },
          "400": {
            "description": "Tidak ada selektor transaksi yang diberikan.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "transaction_uuids": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                },
                "example": {
                  "transaction_uuids": [
                    "This field is required unless delete_all is true."
                  ]
                }
              }
            }
          },
          "403": {
            "description": "Kunci API tidak dapat menghapus transaksi. Endpoint memerlukan `write:transactions`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "Setidaknya satu transaksi yang dipilih tercantum dalam laporan regulasi yang telah difinalisasi. Tidak ada yang dihapus.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InFiledReportError"
                }
              }
            }
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/travel-rule/networks/": {
      "get": {
        "summary": "Dapatkan jaringan Travel Rule",
        "description": "Baca, untuk aplikasi ini, status sebenarnya dari setiap jaringan: apakah jaringan mengirim melalui keanggotaan Anda sendiri atau melalui milik Didit, dan alasan mengapa belum bisa. Juga mengembalikan kuesioner uji tuntas dan peserta Anda. Pembacaan tidak membuat apa pun.",
        "operationId": "getTravelRuleNetworks",
        "x-didit-sdk": {
          "resource": "travel_rule.networks",
          "method": "retrieve",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Travel Rule"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET https://verification.didit.me/v3/travel-rule/networks/ \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.travel_rule.networks.retrieve()\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.travelRule.networks.retrieve();\nconsole.log(result);"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.travelRule().networks().retrieve();\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->travelRule->networks->retrieve();\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.travel_rule.networks.retrieve\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.TravelRule.Networks.RetrieveAsync();\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "Status jaringan, kuesioner, dan peserta.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TravelRuleNetworksOverview"
                },
                "examples": {
                  "Before the questionnaire": {
                    "value": {
                      "platform_networks_enabled": false,
                      "questionnaire": {
                        "status": "draft",
                        "answers": {},
                        "submitted_at": null,
                        "reviewed_at": null,
                        "review_note": "",
                        "history": [],
                        "updated_at": null
                      },
                      "participants": [],
                      "networks": {
                        "gtr": {
                          "rail": "GTR",
                          "mode": "unavailable",
                          "state": "didit_onboarding",
                          "reason": "didit_membership_not_live",
                          "platform_available": false,
                          "connected": false,
                          "participant": null,
                          "vasps_reachable": 0,
                          "routed_30d": 0
                        },
                        "trust": {
                          "rail": "TRUST",
                          "mode": "unavailable",
                          "state": "unavailable",
                          "reason": "own_membership_only",
                          "platform_available": false,
                          "connected": false,
                          "participant": null,
                          "vasps_reachable": 0,
                          "routed_30d": 0
                        },
                        "verifyvasp": {
                          "rail": "VERIFYVASP",
                          "mode": "unavailable",
                          "state": "didit_onboarding",
                          "reason": "didit_membership_not_live",
                          "platform_available": false,
                          "connected": false,
                          "participant": null,
                          "vasps_reachable": 0,
                          "routed_30d": 0
                        },
                        "sygna": {
                          "rail": "SYGNA",
                          "mode": "unavailable",
                          "state": "didit_onboarding",
                          "reason": "didit_membership_not_live",
                          "platform_available": false,
                          "connected": false,
                          "participant": null,
                          "vasps_reachable": 0,
                          "routed_30d": 0
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Kunci API tidak ada atau tidak valid."
          }
        }
      }
    },
    "/v3/travel-rule/networks/questionnaire/": {
      "get": {
        "summary": "Dapatkan kuesioner jaringan",
        "description": "Baca kuesioner uji tuntas jaringan Didit untuk aplikasi ini, statusnya, serta catatan peninjauan Didit. Aplikasi yang belum pernah menyimpannya akan membaca draf kosong.",
        "operationId": "getTravelRuleNetworkQuestionnaire",
        "x-didit-sdk": {
          "resource": "travel_rule.networks",
          "method": "retrieve_questionnaire",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Travel Rule"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET https://verification.didit.me/v3/travel-rule/networks/questionnaire/ \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.travel_rule.networks.retrieve_questionnaire()\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.travelRule.networks.retrieveQuestionnaire();\nconsole.log(result);"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.travelRule().networks().retrieveQuestionnaire();\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->travelRule->networks->retrieveQuestionnaire();\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.travel_rule.networks.retrieve_questionnaire\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.TravelRule.Networks.RetrieveQuestionnaireAsync();\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "Kuesioner.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TravelRuleNetworkQuestionnaire"
                }
              }
            }
          },
          "401": {
            "description": "Kunci API tidak ada atau tidak valid."
          }
        }
      },
      "put": {
        "summary": "Simpan jawaban kuesioner jaringan",
        "description": "Simpan jawaban kuesioner saat berstatus draft atau changes_requested. Penyimpanan bersifat parsial: jawaban yang tidak Anda kirimkan akan tetap disimpan.",
        "operationId": "updateTravelRuleNetworkQuestionnaire",
        "x-didit-sdk": {
          "resource": "travel_rule.networks",
          "method": "update_questionnaire",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Travel Rule"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X PUT https://verification.didit.me/v3/travel-rule/networks/questionnaire/ \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"legal_name\": \"Example VASP Ltd\", \"incorporation_country\": \"ES\", \"aml_ctf_policy_attested\": true}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.travel_rule.networks.update_questionnaire(\n    legal_name=\"Example VASP Ltd\",\n    incorporation_country=\"ES\",\n    aml_ctf_policy_attested=True,\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.travelRule.networks.updateQuestionnaire({\n  legal_name: \"Example VASP Ltd\",\n  incorporation_country: \"ES\",\n  aml_ctf_policy_attested: true,\n});\nconsole.log(result);"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.TravelRuleNetworkQuestionnaireAnswers;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.travelRule().networks().updateQuestionnaire(TravelRuleNetworkQuestionnaireAnswers.builder()\n        .legalName(\"Example VASP Ltd\")\n        .incorporationCountry(\"ES\")\n        .amlCtfPolicyAttested(true)\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->travelRule->networks->updateQuestionnaire([\n    'legal_name' => 'Example VASP Ltd',\n    'incorporation_country' => 'ES',\n    'aml_ctf_policy_attested' => true,\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.travel_rule.networks.update_questionnaire(\n  legal_name: \"Example VASP Ltd\",\n  incorporation_country: \"ES\",\n  aml_ctf_policy_attested: true\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.TravelRule.Networks.UpdateQuestionnaireAsync(new TravelRuleNetworkQuestionnaireAnswers\n{\n    LegalName = \"Example VASP Ltd\",\n    IncorporationCountry = \"ES\",\n    AmlCtfPolicyAttested = true,\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TravelRuleNetworkQuestionnaireAnswers"
              },
              "example": {
                "legal_name": "Example VASP Ltd",
                "incorporation_country": "ES",
                "aml_ctf_policy_attested": true
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Kuesioner dengan jawaban yang telah digabungkan.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TravelRuleNetworkQuestionnaire"
                }
              }
            }
          },
          "400": {
            "description": "Kesalahan validasi, dengan kunci berupa kolom."
          },
          "401": {
            "description": "Kunci API tidak ada atau tidak valid."
          },
          "403": {
            "description": "Akses jaringan melalui keanggotaan Didit belum dibuka.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string",
                      "enum": [
                        "travel_rule_platform_networks_disabled"
                      ]
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "Kuesioner sedang berada di Didit atau telah diputuskan: kuesioner hanya dapat diubah saat berstatus draft atau changes_requested.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string",
                      "enum": [
                        "travel_rule_questionnaire_not_editable"
                      ]
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v3/travel-rule/networks/questionnaire/submit/": {
      "post": {
        "summary": "Kirim kuesioner jaringan",
        "description": "Kirim kuesioner yang disimpan ke peninjauan Didit. Jawaban yang disimpan harus lengkap: setiap kolom kecuali lei dan data_protection_contact_email, dengan ketiga atestasi bernilai true. Didit menyetujuinya, meminta perubahan (ubah dan kirim lagi), atau menolaknya. Jaringan yang Anda minta saat kuesioner tertunda akan diteruskan ke proses onboarding mereka setelah disetujui.",
        "operationId": "submitTravelRuleNetworkQuestionnaire",
        "x-didit-sdk": {
          "resource": "travel_rule.networks",
          "method": "submit_questionnaire",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Travel Rule"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST https://verification.didit.me/v3/travel-rule/networks/questionnaire/submit/ \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.travel_rule.networks.submit_questionnaire()\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.travelRule.networks.submitQuestionnaire();\nconsole.log(result);"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.travelRule().networks().submitQuestionnaire();\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->travelRule->networks->submitQuestionnaire();\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.travel_rule.networks.submit_questionnaire\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.TravelRule.Networks.SubmitQuestionnaireAsync();\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "Kuesioner yang dikirimkan.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TravelRuleNetworkQuestionnaire"
                }
              }
            }
          },
          "400": {
            "description": "Jawaban yang disimpan tidak lengkap atau tidak valid, dipetakan berdasarkan kolom."
          },
          "401": {
            "description": "Kunci API tidak ada atau tidak valid."
          },
          "403": {
            "description": "Akses jaringan melalui keanggotaan Didit belum dibuka.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string",
                      "enum": [
                        "travel_rule_platform_networks_disabled"
                      ]
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "Kuesioner sedang berada di Didit atau telah diputuskan: kuesioner hanya dapat diubah saat berstatus draft atau changes_requested.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string",
                      "enum": [
                        "travel_rule_questionnaire_not_editable"
                      ]
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v3/travel-rule/networks/{network}/request/": {
      "post": {
        "summary": "Minta jaringan Travel Rule",
        "description": "Minta partisipan aplikasi ini sendiri pada jaringan yang didukung oleh keanggotaan Didit (GTR atau Sygna). Tanpa kuesioner yang disetujui, partisipan menunggu kuesioner tersebut (questionnaire_pending); jika ada, partisipan melanjutkan ke onboarding jaringan (submitted_to_network) dan menjadi aktif setelah jaringan memberikan kode. Idempoten: partisipan yang berstatus pending, onboarding, atau live dikembalikan tanpa perubahan. Jika jaringan menolak pendaftaran (last_error terisi), meminta kembali akan melakukan percobaan ulang. TRUST dan VerifyVASP hanya dapat diakses melalui keanggotaan Anda sendiri: TRUST menerima anggota per VASP, dan VerifyVASP Enclave melayani satu ID VASP.",
        "operationId": "requestTravelRuleNetworkAccess",
        "x-didit-sdk": {
          "resource": "travel_rule.networks",
          "method": "request_access",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Travel Rule"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "network",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "gtr",
                "sygna"
              ]
            },
            "description": "Jaringan untuk bergabung melalui keanggotaan Didit."
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST https://verification.didit.me/v3/travel-rule/networks/gtr/request/ \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.travel_rule.networks.request_access(\n    \"your-network\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.travelRule.networks.requestAccess(\"your-network\");\nconsole.log(result);"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.travelRule().networks().requestAccess(\"your-network\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->travelRule->networks->requestAccess('your-network');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.travel_rule.networks.request_access(\"your-network\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.TravelRule.Networks.RequestAccessAsync(\"your-network\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "Partisipan Anda di jaringan.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TravelRuleNetworkParticipant"
                }
              }
            }
          },
          "400": {
            "description": "Jaringan tidak dikenal, jaringan yang tidak didukung Didit (hubungkan keanggotaan Anda sendiri), atau aplikasi sandbox.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string",
                      "enum": [
                        "travel_rule_network_own_membership_only",
                        "travel_rule_network_sandbox_application"
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Kunci API tidak ada atau tidak valid."
          },
          "403": {
            "description": "Akses jaringan melalui keanggotaan Didit belum dibuka.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string",
                      "enum": [
                        "travel_rule_platform_networks_disabled"
                      ]
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v3/address-validation/": {
      "post": {
        "summary": "Validasi alamat",
        "description": "Konfirmasikan bahwa suatu alamat memang ada dan dapatkan kembali dalam bentuk dinormalisasi: baris pengiriman, komponen, dan koordinatnya. Ini hanya mengonfirmasi alamat; tidak pernah menautkan alamat ke seseorang.\n\n**Permintaan.** Kirim alamat dalam satu baris (`address`) atau sebagai kolom terstruktur (`address_line_1` dan, secara opsional, `address_line_2`, `city`, `region`, `postal_code`), jangan pernah keduanya, dan selalu sertakan `country`-nya (ISO 3166-1 alpha-2 atau alpha-3).\n\n**Hasil.** `address_validation.status` bernilai `verified` (terkonfirmasi hingga ke bangunan), `partially_verified` (hanya terkonfirmasi hingga ke jalan atau di atasnya), `not_verified` (hanya wilayah atau kota yang cocok, atau tidak ada yang cocok) atau `unavailable` (validasi tidak dapat dijalankan). HTTP bernilai `200` untuk setiap permintaan yang selesai, termasuk `unavailable`; coba lagi hasil `unavailable` nanti.\n\n**Penagihan.** Panggilan produksi berbiaya $0.10 per alamat yang divalidasi. Hasil `unavailable` tidak dikenakan biaya. Tidak ada yang disimpan selain catatan penggunaan: tidak ada sesi yang dibuat dan hasilnya hanya dikembalikan dalam respons ini.\n\n**Sandbox.** Kunci sandbox memvalidasi permintaan dan selalu mengembalikan hasil deterministik `verified` yang mencerminkan alamat yang dikirim, tanpa menghabiskan kredit.\n\n**Autentikasi.** Kirim kunci API aplikasi Anda di `x-api-key`. Kredensial yang hilang atau tidak valid mengembalikan `403` - API ini tidak pernah mengembalikan `401`.\n\n**Batas laju.** Anggaran penulisan bersama sebesar 300 permintaan per menit per kunci API di seluruh endpoint POST/PATCH/DELETE (pembuatan transaksi dan penyerapan event memiliki anggaran terpisah sebesar 600).",
        "operationId": "post_v3_address_validation",
        "x-didit-sdk": {
          "resource": "address_validation",
          "method": "validate",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Standalone APIs"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST https://verification.didit.me/v3/address-validation/ \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"address_line_1\": \"1600 Amphitheatre Pkwy\",\n    \"city\": \"Mountain View\",\n    \"region\": \"CA\",\n    \"postal_code\": \"94043\",\n    \"country\": \"US\"\n  }'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.address_validation.validate(\n    address_line_1=\"1600 Amphitheatre Pkwy\",\n    city=\"Mountain View\",\n    region=\"CA\",\n    postal_code=\"94043\",\n    country=\"US\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.addressValidation.validate({\n  address_line_1: \"1600 Amphitheatre Pkwy\",\n  city: \"Mountain View\",\n  region: \"CA\",\n  postal_code: \"94043\",\n  country: \"US\",\n});\nconsole.log(result);"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.AddressValidationRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.addressValidation().validate(AddressValidationRequest.builder()\n        .addressLine1(\"1600 Amphitheatre Pkwy\")\n        .city(\"Mountain View\")\n        .region(\"CA\")\n        .postalCode(\"94043\")\n        .country(\"US\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->addressValidation->validate([\n    'address_line_1' => '1600 Amphitheatre Pkwy',\n    'city' => 'Mountain View',\n    'region' => 'CA',\n    'postal_code' => '94043',\n    'country' => 'US',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.address_validation.validate(\n  address_line_1: \"1600 Amphitheatre Pkwy\",\n  city: \"Mountain View\",\n  region: \"CA\",\n  postal_code: \"94043\",\n  country: \"US\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.AddressValidation.ValidateAsync(new AddressValidationRequest\n{\n    AddressLine1 = \"1600 Amphitheatre Pkwy\",\n    City = \"Mountain View\",\n    Region = \"CA\",\n    PostalCode = \"94043\",\n    Country = \"US\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AddressValidationRequest"
              },
              "examples": {
                "Structured": {
                  "summary": "Kolom alamat terstruktur",
                  "value": {
                    "address_line_1": "1600 Amphitheatre Pkwy",
                    "city": "Mountain View",
                    "region": "CA",
                    "postal_code": "94043",
                    "country": "US"
                  }
                },
                "One line": {
                  "summary": "Seluruh alamat dalam satu baris",
                  "value": {
                    "address": "Paseo de la Castellana 259, 28046 Madrid",
                    "country": "ES"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Validasi selesai. Baca `address_validation.status`; HTTP selalu `200` untuk permintaan yang selesai.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AddressValidationResponse"
                },
                "examples": {
                  "Verified": {
                    "summary": "Alamat riil, terkonfirmasi hingga tingkat bangunan",
                    "value": {
                      "request_id": "6f7d2c1e-1c5a-4a1e-9b8f-2a1f0f4b9c3d",
                      "address_validation": {
                        "status": "verified",
                        "verification_level": "premise",
                        "address": {
                          "address_line_1": "1600 Amphitheatre Pkwy",
                          "address_line_2": null,
                          "city": "Mountain View",
                          "region": "CA",
                          "postal_code": "94043-1351",
                          "country": "US"
                        },
                        "formatted_address": "1600 Amphitheatre Pkwy, Mountain View CA 94043-1351",
                        "latitude": 37.422022,
                        "longitude": -122.08429
                      },
                      "created_at": "2026-10-27T11:20:00.000000+00:00"
                    }
                  },
                  "Not verified": {
                    "summary": "Jalan yang dibuat-buat: hanya kota yang cocok",
                    "value": {
                      "request_id": "0b9e3f4a-6c2d-4e8b-a1f7-5d3c2b1a0e9f",
                      "address_validation": {
                        "status": "not_verified",
                        "verification_level": "locality",
                        "address": {
                          "address_line_1": "Calle Inventada Que No Existe 99999 28046",
                          "address_line_2": null,
                          "city": "Madrid",
                          "region": "Madrid",
                          "postal_code": null,
                          "country": "ES"
                        },
                        "formatted_address": "Calle Inventada Que No Existe 99999 28046, Madrid, MADRID, SPAIN",
                        "latitude": 40.42603054,
                        "longitude": -3.68645331
                      },
                      "created_at": "2026-10-27T11:21:00.000000+00:00"
                    }
                  },
                  "Unavailable": {
                    "summary": "Validasi tidak dapat dijalankan; tidak dikenakan biaya",
                    "value": {
                      "request_id": "3c1b2a0f-9e8d-4c7b-b6a5-1f0e9d8c7b6a",
                      "address_validation": {
                        "status": "unavailable",
                        "verification_level": null,
                        "address": null,
                        "formatted_address": null,
                        "latitude": null,
                        "longitude": null
                      },
                      "created_at": "2026-10-27T11:22:00.000000+00:00"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/AddressValidationValidationError"
          },
          "403": {
            "$ref": "#/components/responses/AddressValidationPermissionDenied"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitedWrite"
          }
        }
      }
    },
    "/v3/travel-rule/wallet-proofs/": {
      "get": {
        "summary": "Mencantumkan daftar bukti dompet berupa tangkapan layar untuk ditinjau",
        "description": "Antrean peninjauan Anda untuk bukti kepemilikan dompet berupa tangkapan layar. Tangkapan layar adalah satu-satunya bukti yang tidak dapat diperiksa sendiri oleh Didit: setelah pengguna akhir mengunggahnya dari widget, bukti tersebut berstatus PENDING hingga Anda menyetujui atau menolaknya dengan POST /v3/travel-rule/wallet-proofs/{proof_uuid}/decision/. Yang paling lama terlebih dahulu, sehingga antrean dikerjakan dari bukti yang telah menunggu paling lama. Hanya tangkapan layar yang diunggah yang muncul, tidak pernah bukti yang file-nya belum diunggah oleh pengguna akhir, dan tidak pernah bukti pada dompet yang telah Anda hapus dari buku alamat Anda (Didit menutupnya sebagai OWNERSHIP_CHANGED).",
        "operationId": "listTravelRuleWalletProofs",
        "x-didit-sdk": {
          "resource": "travel_rule.wallet_proofs",
          "method": "list",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Travel Rule"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "status",
            "in": "query",
            "description": "Bukti mana yang akan dicantumkan. Default ke PENDING, yaitu bukti yang masih harus diputuskan.",
            "schema": {
              "type": "string",
              "enum": [
                "PENDING",
                "VERIFIED",
                "REJECTED",
                "EXPIRED"
              ],
              "default": "PENDING"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 50,
              "minimum": 1
            }
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 0,
              "minimum": 0
            }
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl https://verification.didit.me/v3/travel-rule/wallet-proofs/?status=PENDING \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nfor item in client.travel_rule.wallet_proofs.list():\n    print(item)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nfor await (const item of didit.travelRule.walletProofs.list()) {\n  console.log(item);\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nfor (var item : client.travelRule().walletProofs().list()) {\n    System.out.println(item);\n}"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\nforeach ($didit->travelRule->walletProofs->list() as $item) {\n    print_r($item->toArray());\n}"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.travel_rule.wallet_proofs.list.auto_paging_each do |item|\n  puts item.to_h\nend"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.TravelRule.WalletProofs.ListAsync())\n{\n    Console.WriteLine(JsonSerializer.Serialize(item));\n}"
          }
        ],
        "responses": {
          "200": {
            "description": "Bukti tangkapan layar terpaginasi. Jumlah tepat hingga 100 dan dibatasi pada 100 jika di atasnya.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "count": {
                      "type": "integer"
                    },
                    "next": {
                      "type": "string",
                      "nullable": true
                    },
                    "previous": {
                      "type": "string",
                      "nullable": true
                    },
                    "results": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/TravelRuleWalletProofReview"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Status tidak dikenal."
          },
          "401": {
            "description": "x-api-key tidak ada atau tidak valid."
          },
          "403": {
            "description": "Pemanggil tidak memiliki izin transaksi."
          }
        }
      }
    },
    "/v3/travel-rule/wallet-proofs/{proof_uuid}/decision/": {
      "post": {
        "summary": "Setujui atau tolak bukti dompet berupa tangkapan layar",
        "description": "Putuskan bukti tangkapan layar dari antrean peninjauan Anda. approve memverifikasi bukti dan entri buku alamat serta menerapkan kepemilikan ke transfer yang menjadi tujuan penerbitan sesi widget, persis seperti yang dilakukan verifikasi tanda tangan. Tangkapan layar tidak pernah mengonfirmasi transfer yang dikirim pelanggan Didit lain melalui jalur INTERNAL: hal tersebut memerlukan pesan bertanda tangan atau setoran uji coba. reject menutup bukti sebagai REJECTED dengan failure_reason REVIEW_REJECTED; pengguna akhir dapat memulai bukti baru dari widget. Catatan disimpan bersama bukti.",
        "operationId": "decideTravelRuleWalletProof",
        "x-didit-sdk": {
          "resource": "travel_rule.wallet_proofs",
          "method": "decide",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Travel Rule"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "proof_uuid",
            "in": "path",
            "required": true,
            "description": "proof_id dari antrean peninjauan.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TravelRuleWalletProofDecision"
              },
              "example": {
                "decision": "approve",
                "note": "Address matches the wallet app."
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST https://verification.didit.me/v3/travel-rule/wallet-proofs/{proof_uuid}/decision/ \\\n  -H 'x-api-key: YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"decision\": \"approve\", \"note\": \"Address matches the wallet app.\"}'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.travel_rule.wallet_proofs.decide(\n    \"11111111-2222-3333-4444-555555555555\",\n    decision=\"approve\",\n    note=\"Address matches the wallet app.\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.travelRule.walletProofs.decide(\"11111111-2222-3333-4444-555555555555\", {\n  decision: \"approve\",\n  note: \"Address matches the wallet app.\",\n});\nconsole.log(result);"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.TravelRuleWalletProofDecision;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.travelRule().walletProofs().decide(\"11111111-2222-3333-4444-555555555555\", TravelRuleWalletProofDecision.builder()\n        .decision(TravelRuleWalletProofDecision.Decision.of(\"approve\"))\n        .note(\"Address matches the wallet app.\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->travelRule->walletProofs->decide('11111111-2222-3333-4444-555555555555', [\n    'decision' => 'approve',\n    'note' => 'Address matches the wallet app.',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.travel_rule.wallet_proofs.decide(\n  \"11111111-2222-3333-4444-555555555555\",\n  decision: \"approve\",\n  note: \"Address matches the wallet app.\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.TravelRule.WalletProofs.DecideAsync(\"11111111-2222-3333-4444-555555555555\", new TravelRuleWalletProofDecision\n{\n    Decision = \"approve\",\n    Note = \"Address matches the wallet app.\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "Bukti yang telah ditetapkan.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TravelRuleWalletProofReview"
                }
              }
            }
          },
          "400": {
            "description": "Keputusan tidak valid, atau catatan lebih dari 512 karakter."
          },
          "401": {
            "description": "x-api-key tidak ada atau tidak valid."
          },
          "403": {
            "description": "Pemanggil tidak memiliki izin transaksi."
          },
          "404": {
            "description": "Tidak ada bukti tangkapan layar yang dikirimkan dengan id ini di aplikasi Anda."
          },
          "409": {
            "description": "Bukti telah diputuskan (isi respons memuat statusnya), atau kode OWNERSHIP_CHANGED: pemegang dompet telah berubah atau dompet dihapus setelah sesi widget dibuat, sehingga bukti ditutup dan pemegang saat ini memerlukan bukti baru.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TravelRuleWidgetProofError"
                }
              }
            }
          }
        }
      }
    },
    "/v3/travel-rule/widget/{token}/proofs/": {
      "post": {
        "summary": "Mulai pembuktian kepemilikan dompet",
        "description": "Endpoint publik yang diidentifikasi dengan token sesi widget, tidak memerlukan kunci API: widget yang di-hosting memanggilnya saat pengguna akhir memilih metode bukti. Bukti ada, dan dihitung dalam funnel bukti Anda, hanya dari panggilan ini. Memilih metode yang sama lagi mengembalikan bukti yang sudah terbuka (200, challenge atau jumlah deposit yang sama) alih-alih memulai yang kedua; memilih metode lain menutup bukti yang belum selesai sebagai METHOD_SWITCHED, kecuali screenshot yang sudah dikirimkan atau deposit uji yang masih diperiksa. MESSAGE_SIGNING mengembalikan challenge untuk ditandatangani; SATOSHI_TEST mengembalikan alamat deposit, jumlah pasti, dan jendela waktu; SELF_DECLARATION langsung diverifikasi seketika (status VERIFIED). Format tanda tangan yang diverifikasi per rumpun rantai: rantai EVM menerima tanda tangan personal_sign (EIP-191), dienkode hex; Bitcoin menerima tanda tangan signmessage BIP-137 (alamat P2PKH, P2SH-P2WPKH, dan P2WPKH) atau tanda tangan sederhana BIP-322 (alamat P2WPKH dan P2TR), dienkode base64; Solana menerima tanda tangan Ed25519 atas challenge, dienkode base58; Tron menerima tanda tangan signMessageV2 (TIP-191), dienkode hex. Tanda tangan BIP-322 penuh atau bukti dana, atau alamat multisig, gagal dengan SIGNATURE_UNSUPPORTED_SCHEME.",
        "operationId": "createTravelRuleWidgetProof",
        "x-didit-sdk": {
          "resource": "travel_rule",
          "method": "create_widget_proof",
          "auth": "public",
          "server": false
        },
        "tags": [
          "Travel Rule"
        ],
        "security": [
          {}
        ],
        "parameters": [
          {
            "name": "token",
            "in": "path",
            "required": true,
            "description": "Token sesi yang tidak transparan yang dikembalikan saat sesi widget dibuat.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TravelRuleWidgetProofCreate"
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST https://verification.didit.me/v3/travel-rule/widget/{token}/proofs/ \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"method\": \"MESSAGE_SIGNING\"}'"
          }
        ],
        "responses": {
          "201": {
            "description": "Bukti PENDING baru (VERIFIED untuk SELF_DECLARATION).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TravelRuleWidgetProofSummary"
                }
              }
            }
          },
          "200": {
            "description": "Bukti yang sudah terbuka untuk metode ini, dilanjutkan.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TravelRuleWidgetProofSummary"
                }
              }
            }
          },
          "400": {
            "description": "Body tidak valid, dompet yang tidak cocok dengan transfer, SCREENSHOT tidak diizinkan, atau kode CHAIN_UNSUPPORTED saat metode tidak tersedia pada blockchain tersebut.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TravelRuleWidgetProofError"
                }
              }
            }
          },
          "403": {
            "description": "SELF_DECLARATION tidak diizinkan untuk aplikasi ini."
          },
          "404": {
            "description": "Token tidak dikenal."
          },
          "409": {
            "description": "kode OWNERSHIP_CHANGED: pemegang dompet berubah atau dompet dihapus setelah sesi dibuat; buat sesi baru untuk pemegang saat ini. Juga dikembalikan untuk SATOSHI_TEST ketika sesi tidak memiliki satoshi_deposit_address, dan ketika sesi tidak memiliki sisa percobaan (tidak ada kode; isi memuat max_attempts, attempts_used, dan attempts_remaining 0): buat sesi baru.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TravelRuleWidgetProofError"
                }
              }
            }
          },
          "410": {
            "description": "Sesi kedaluwarsa."
          }
        }
      }
    },
    "/v3/travel-rule/widget/{token}/proofs/{proof_id}/verify/": {
      "post": {
        "summary": "Kirim bukti kepemilikan dompet",
        "description": "Endpoint publik yang diidentifikasi dengan token sesi widget, tidak memerlukan kunci API. Kirim bukti yang dibutuhkan metode bukti: tanda tangan untuk MESSAGE_SIGNING, txid untuk SATOSHI_TEST (JSON), atau file untuk SCREENSHOT (multipart). Setiap pengiriman dihitung sebagai percobaan. Tanda tangan yang tidak terverifikasi, atau deposit yang tidak cocok, merespons 400 dengan kode dan membiarkan bukti tetap PENDING agar pengguna akhir dapat mencoba lagi. Deposit yang terlihat tetapi belum dikonfirmasi merespons 200 dengan status PENDING dan diperiksa ulang secara otomatis hingga jendela waktu ditutup. Screenshot merespons 200 dengan status PENDING dan menunggu di antrean peninjauan Anda (GET /v3/travel-rule/wallet-proofs/). Bukti EXPIRED atau REJECTED tidak akan pernah diverifikasi kemudian: mulai yang baru. Format tanda tangan yang diverifikasi per rumpun rantai: rantai EVM menerima tanda tangan personal_sign (EIP-191), dienkode hex; Bitcoin menerima tanda tangan signmessage BIP-137 (alamat P2PKH, P2SH-P2WPKH, dan P2WPKH) atau tanda tangan sederhana BIP-322 (alamat P2WPKH dan P2TR), dienkode base64; Solana menerima tanda tangan Ed25519 atas challenge, dienkode base58; Tron menerima tanda tangan signMessageV2 (TIP-191), dienkode hex. Tanda tangan BIP-322 penuh atau bukti dana, atau alamat multisig, gagal dengan SIGNATURE_UNSUPPORTED_SCHEME.",
        "operationId": "verifyTravelRuleWidgetProof",
        "x-didit-sdk": {
          "resource": "travel_rule",
          "method": "verify_widget_proof",
          "auth": "public",
          "server": false
        },
        "tags": [
          "Travel Rule"
        ],
        "security": [
          {}
        ],
        "parameters": [
          {
            "name": "token",
            "in": "path",
            "required": true,
            "description": "Token sesi yang tidak transparan yang dikembalikan saat sesi widget dibuat.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "proof_id",
            "in": "path",
            "required": true,
            "description": "proof_id dikembalikan saat bukti dimulai.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "signature": {
                    "type": "string",
                    "description": "MESSAGE_SIGNING: tanda tangan dompet atas tantangan bukti."
                  },
                  "txid": {
                    "type": "string",
                    "description": "SATOSHI_TEST: id transaksi dari deposit uji coba."
                  }
                }
              }
            },
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "required": [
                  "file"
                ],
                "properties": {
                  "file": {
                    "type": "string",
                    "format": "binary",
                    "description": "SCREENSHOT: gambar yang menunjukkan dompet di aplikasi dompet milik pengguna akhir."
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST https://verification.didit.me/v3/travel-rule/widget/{token}/proofs/{proof_id}/verify/ \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"signature\": \"0x...\"}'"
          }
        ],
        "responses": {
          "200": {
            "description": "VERIFIED, atau masih PENDING (tangkapan layar yang menunggu peninjauan, deposit yang belum terindeks atau belum dikonfirmasi, dengan kode DEPOSIT_NOT_FOUND atau DEPOSIT_UNCONFIRMED).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TravelRuleWidgetProofVerifyResult"
                }
              }
            }
          },
          "400": {
            "description": "Bukti tidak ada; upaya gagal yang membuat bukti berstatus PENDING agar pengguna akhir dapat mencoba lagi (kode SIGNATURE_INVALID, SIGNATURE_UNSUPPORTED_SCHEME, atau DEPOSIT_LOOKUP_FAILED); atau deposit uji yang menolak bukti (kode DEPOSIT_MISMATCH, DEPOSIT_STALE, atau TXID_REUSED, status REJECTED, beserta jumlah percobaan sesi): memilih metode lagi akan memulai bukti baru selama attempts_remaining di atas 0.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TravelRuleWidgetProofError"
                }
              }
            }
          },
          "404": {
            "description": "Token tidak dikenal, atau tidak ada bukti tersebut pada sesi ini."
          },
          "409": {
            "description": "kode OWNERSHIP_CHANGED (bukti ditutup dengannya); bukti yang ditutup (REJECTED atau EXPIRED), dengan statusnya, kode penutupannya, dan jumlah percobaan sesi: pilih metode lagi untuk memulai bukti baru; atau bukti SELF_DECLARATION, yang diverifikasi saat dimulai.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TravelRuleWidgetProofError"
                }
              }
            }
          },
          "410": {
            "description": "Sesi kedaluwarsa, atau kode WINDOW_EXPIRED saat jendela pengujian satoshi ditutup.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TravelRuleWidgetProofError"
                }
              }
            }
          }
        }
      }
    },
    "/v3/id-verification/wallets/verifications/{request_id}/response/": {
      "post": {
        "operationId": "submit_wallet_verification_response",
        "x-didit-sdk": {
          "resource": "id_wallets",
          "method": "submit_verification_response",
          "auth": "api_key",
          "server": true
        },
        "description": "Dompet untuk Digital Credentials API (Google Wallet): kirim apa yang dikembalikan dompet ke halaman atau aplikasi Anda untuk verifikasi yang next_action-nya adalah request_digital_credential. Didit mendekripsinya, memeriksa tanda tangan penerbit terhadap root penerbit tepercaya, setiap nilai yang dikembalikan terhadap digest yang ditandatanganinya, dan tanda tangan perangkat atas origin Anda dan permintaan ini, lalu memutuskan verifikasi: diverifikasi (ditagih sekali) atau ditolak dengan kode kesalahan. Sekali pakai: pengiriman kedua mengembalikan verifikasi yang telah diputuskan.",
        "summary": "Kirim respons dompet",
        "parameters": [
          {
            "in": "path",
            "name": "request_id",
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "request_id yang dikembalikan oleh endpoint untuk memulai.",
            "required": true
          }
        ],
        "tags": [
          "Digital ID wallets"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiWalletDigitalCredentialResponseRequest"
              },
              "example": {
                "response": {
                  "protocol": "openid4vp-v1-signed",
                  "data": {
                    "response": "<compact JWE returned by the wallet>"
                  }
                }
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiWalletDigitalCredentialResponseRequest"
              },
              "example": {
                "response": {
                  "protocol": "openid4vp-v1-signed",
                  "data": {
                    "response": "<compact JWE returned by the wallet>"
                  }
                }
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiWalletDigitalCredentialResponseRequest"
              },
              "example": {
                "response": {
                  "protocol": "openid4vp-v1-signed",
                  "data": {
                    "response": "<compact JWE returned by the wallet>"
                  }
                }
              }
            }
          },
          "required": true
        },
        "security": [
          {
            "ApiKeyAuth": []
          },
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationResponse"
                },
                "example": {
                  "request_id": "00000000-0000-4000-8000-000000000001",
                  "wallet_verification": {
                    "wallet": {
                      "id": "google_wallet",
                      "name": "Google Wallet",
                      "issuing_authority": "Google Wallet (ID pass) and US state issuers (mobile driving licence)"
                    },
                    "country": "USA",
                    "status": "Approved",
                    "outcome": "verified",
                    "error": null,
                    "interaction": "digital_credentials",
                    "simulated": false,
                    "expires_at": "2026-01-01T10:10:00Z",
                    "next_action": null,
                    "identity": {
                      "full_name": "Alex Example",
                      "first_name": "Alex",
                      "last_name": "Example",
                      "date_of_birth": "1990-01-31",
                      "nationality": "USA",
                      "issuing_state": "USA"
                    },
                    "attributes": {
                      "document_number": "X0000000",
                      "document_expiry_date": "2030-01-31"
                    },
                    "level_of_assurance": "substantial",
                    "verified_at": "2026-01-01T10:01:00Z",
                    "signature_valid": true,
                    "credential_type": "person_identification"
                  },
                  "vendor_data": "your-customer-reference",
                  "metadata": {
                    "reference": "example"
                  },
                  "created_at": "2026-01-01T10:00:00Z"
                }
              }
            },
            "description": ""
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiClientCredentialsForbiddenErrorMessage"
                }
              }
            },
            "description": "Kredensial tidak ada (x-api-key atau Authorization: Bearer)."
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "kesalahan not_found: tidak ada verifikasi dompet dari aplikasi ini yang memiliki request_id ini."
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationStartBadRequest"
                }
              }
            },
            "description": "Error validasi kolom ({field: [messages]})."
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "kesalahan not_a_digital_credentials_wallet: verifikasi ini tidak menerima respons dompet."
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "kesalahan wallet_not_configured: lingkungan ini tidak dapat memverifikasi dompet."
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL",
            "source": "curl --request POST \\\n  --url https://verification.didit.me/v3/id-verification/wallets/verifications/REQUEST_ID/response/ \\\n  --header 'x-api-key: YOUR_API_KEY' \\\n  --header 'Content-Type: application/json' \\\n  --data '{\n  \"response\": {\n    \"protocol\": \"openid4vp-v1-signed\",\n    \"data\": {\n      \"response\": \"<compact JWE returned by the wallet>\"\n    }\n  }\n}'"
          }
        ]
      }
    },
    "/v3/id-verification/wallets/google-wallet/": {
      "post": {
        "operationId": "start_google_wallet_wallet_verification",
        "x-didit-sdk": {
          "resource": "id_wallets",
          "method": "start_google_wallet",
          "auth": "api_key",
          "server": true
        },
        "description": "Mulai proses masuk Google Wallet (Google Wallet (ID pass) dan penerbit negara bagian AS (surat izin mengemudi seluler); USA, GBR, BRA, SGP, TWN) tanpa alur kerja apa pun. Ditagih sekali, hanya ketika identitas diverifikasi. Respons membawa next_action.type=request_digital_credential dengan permintaan yang ditandatangani Didit untuk aplikasi Anda, yang hanya dapat digunakan dari origin. Dalam gestur pengguna di sana, teruskan next_action.digital_credentials.request ke navigator.credentials.get({digital: ...}) (atau ke Android Credential Manager sebagai GetDigitalCredentialOption requestJson), lalu lakukan POST terhadap data yang dikembalikan dompet ke /v3/id-verification/wallets/verifications/{request_id}/response/. Browser menyediakan kode QR-nya sendiri saat dompet berada di perangkat lain. Aplikasi sandbox mendapatkan simulasi deterministik (simulated: true) yang tidak pernah menghubungi penyedia.",
        "summary": "Mulai verifikasi Google Wallet",
        "parameters": [
          {
            "in": "header",
            "name": "Idempotency-Key",
            "schema": {
              "type": "string"
            },
            "description": "Kunci keamanan coba lagi opsional (maks 255 karakter). Mencoba lagi dengan kunci, dompet, dan body yang sama akan mengembalikan verifikasi asli tanpa memulai proses masuk kedua; kunci yang sama dengan dompet atau body lain akan mengembalikan 409 idempotency_key_reused."
          }
        ],
        "tags": [
          "Digital ID wallets"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiGoogleWalletWalletVerificationStartRequest"
              },
              "example": {
                "country": "USA",
                "vendor_data": "your-customer-reference",
                "metadata": {
                  "reference": "example"
                },
                "origin": "https://app.example.com"
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiGoogleWalletWalletVerificationStartRequest"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/DigitalIdWalletApiGoogleWalletWalletVerificationStartRequest"
              }
            }
          },
          "required": true
        },
        "security": [
          {
            "ApiKeyAuth": []
          },
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationResponse"
                },
                "example": {
                  "request_id": "00000000-0000-4000-8000-000000000001",
                  "wallet_verification": {
                    "wallet": {
                      "id": "google_wallet",
                      "name": "Google Wallet",
                      "issuing_authority": "Google Wallet (ID pass) and US state issuers (mobile driving licence)"
                    },
                    "country": "USA",
                    "status": "Not Finished",
                    "outcome": "pending",
                    "error": null,
                    "interaction": "digital_credentials",
                    "simulated": false,
                    "expires_at": "2026-01-01T10:10:00Z",
                    "next_action": {
                      "type": "request_digital_credential",
                      "digital_credentials": {
                        "protocol": "openid4vp-v1-signed",
                        "request": {
                          "requests": [
                            {
                              "protocol": "openid4vp-v1-signed",
                              "data": {
                                "request": "<compact JWS signed by Didit>"
                              }
                            }
                          ]
                        }
                      }
                    },
                    "identity": null,
                    "attributes": null,
                    "level_of_assurance": null,
                    "verified_at": null,
                    "signature_valid": null,
                    "credential_type": "person_identification"
                  },
                  "vendor_data": "your-customer-reference",
                  "metadata": {
                    "reference": "example"
                  },
                  "created_at": "2026-01-01T10:00:00Z"
                }
              }
            },
            "description": ""
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationStartBadRequest"
                }
              }
            },
            "description": "Error validasi kolom ({field: [messages]}), atau error return_url_invalid, return_url_not_allowed, origin_invalid, origin_not_allowed, invalid_personal_code, invalid_phone_number, atau idempotency_key_invalid."
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationStartForbidden"
                }
              }
            },
            "description": "Kredensial tidak ada ({detail}), atau kesalahan wallet_unavailable, insufficient_credits, atau contract_rate_missing."
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "kesalahan idempotency_key_reused atau idempotency_key_in_progress (dengan Retry-After)."
          },
          "502": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "kesalahan wallet_provider_unavailable: penyedia tidak dapat memulai; tidak ada yang dibuat."
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
                }
              }
            },
            "description": "kesalahan wallet_not_configured: lingkungan ini tidak dapat menjangkau dompet."
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL",
            "source": "curl --request POST \\\n  --url https://verification.didit.me/v3/id-verification/wallets/google-wallet/ \\\n  --header 'x-api-key: YOUR_API_KEY' \\\n  --header 'Idempotency-Key: your-unique-attempt-key' \\\n  --header 'Content-Type: application/json' \\\n  --data '{\n  \"country\": \"USA\",\n  \"vendor_data\": \"your-customer-reference\",\n  \"metadata\": {\n    \"reference\": \"example\"\n  },\n  \"origin\": \"https://app.example.com\"\n}'"
          }
        ],
        "x-didit-wallet-id": "google_wallet"
      }
    },
    "/v3/session/{sessionId}/kyb/documents/": {
      "post": {
        "summary": "Unggah dokumen KYB ke sesi",
        "description": "Unggah satu atau beberapa dokumen perusahaan (anggaran dasar, daftar pemegang saham, akta pendirian, ...) ke langkah Dokumen KYB pada sesi Verifikasi Bisnis, dari server Anda sendiri alih-alih halaman yang di-hosting. Didit menjalankan alur pemrosesan yang di-hosting: kompresi, OCR, pemeriksaan manipulasi dan lintas dokumen, pengelompokan dokumen, serta melanjutkan sesi ketika grup dokumen yang diperlukan telah terpenuhi. Langkah ini dikenai satu biaya tetap berapa pun jumlah file yang Anda kirim. Sesi harus terbuka dan berada pada langkah Dokumen KYB, dan perusahaan yang dipilih pada langkah registri harus ada. Baca pihak-pihak yang disebutkan dalam dokumen dengan `GET /v3/session/{sessionId}/kyb/extracted-parties/`. Memerlukan `write:businesses`.",
        "operationId": "post_v3_session_kyb_documents",
        "x-didit-sdk": {
          "resource": "sessions",
          "method": "upload_kyb_documents",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Sessions"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "sessionId",
            "in": "path",
            "required": true,
            "description": "UUID dari sesi Verifikasi Bisnis (KYB). UUID ini harus dimiliki oleh aplikasi yang terkait dengan kunci API.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "33333333-4444-5555-6666-777777777777"
            }
          },
          {
            "name": "node_id",
            "in": "query",
            "required": false,
            "description": "Node alur kerja dari langkah KYB. Hanya diperlukan jika alur kerja memiliki lebih dari satu node KYB; secara default Didit menggunakan node milik sesi itu sendiri.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "required": [
                  "documents"
                ],
                "properties": {
                  "documents": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "format": "binary"
                    },
                    "description": "File yang akan diunggah: JPG, JPEG, PNG, TIFF, WEBP, PDF, atau arsip ZIP yang berisi file-file tersebut. PDF hingga 50 MB, foto hingga 6 MB sebelum kompresi."
                  },
                  "document_passwords": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Satu entri per file di `documents`, dalam urutan yang sama: kata sandi PDF yang diproteksi, kosong untuk file lainnya."
                  },
                  "document_group": {
                    "type": "string",
                    "enum": [
                      "LEGAL_PRESENCE",
                      "COMPANY_DETAILS",
                      "OWNERSHIP_STRUCTURE",
                      "REPRESENTATIVES_AUTHORIZATION"
                    ],
                    "description": "Grup dokumen wajib yang dipenuhi oleh unggahan ini."
                  },
                  "locale": {
                    "type": "string",
                    "maxLength": 10,
                    "description": "Lokal yang digunakan untuk menerjemahkan respons langkah berikutnya."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Dokumen diproses. Saat setiap grup yang diwajibkan terpenuhi, sesi berlanjut dan `next_step` menyebutkan langkah berikutnya; jika tidak, sesi tetap berada pada langkah Dokumen serta `document_groups` dan `document_answer` menyatakan apa yang masih kurang.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "valid": {
                      "type": "boolean"
                    },
                    "next_step": {
                      "type": "string",
                      "nullable": true,
                      "description": "Langkah yang sedang dijalani sesi setelah pengunggahan."
                    },
                    "kyb_status": {
                      "type": "string",
                      "description": "Status pemeriksaan perusahaan."
                    },
                    "document_answer": {
                      "type": "object",
                      "additionalProperties": true,
                      "description": "Hasil per dokumen yang diunggah dan sisa unggahan."
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "valid": true,
                  "next_step": "KYB_KEY_PEOPLE",
                  "kyb_status": "In Progress"
                }
              }
            }
          },
          "400": {
            "description": "Dokumen ditolak (manipulasi, tidak terbaca, atau tidak didukung) atau sesi belum memiliki perusahaan KYB. Coba lagi dengan file lain selama kesempatan mencoba masih ada.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "Pesan kesalahan yang mudah dibaca manusia."
                    }
                  }
                },
                "example": {
                  "message": "No KYB company found. Submit company data first."
                }
              }
            }
          },
          "402": {
            "description": "Organisasi tidak memiliki sisa kredit untuk langkah dokumen.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "Pesan kesalahan yang mudah dibaca manusia."
                    }
                  }
                },
                "example": {
                  "detail": "Insufficient credits."
                }
              }
            }
          },
          "401": {
            "description": "Kunci API dengan cakupan terbatas telah kedaluwarsa. Ini satu-satunya kasus yang mengembalikan `401`: kunci yang hilang, tidak valid, atau dicabut mengembalikan `403`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "Pesan kesalahan yang mudah dibaca manusia."
                    }
                  }
                },
                "examples": {
                  "Expired key": {
                    "summary": "Tanggal kedaluwarsa kunci telah lewat",
                    "value": {
                      "detail": "This API key has expired."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Kegagalan autentikasi atau otorisasi. Kunci yang hilang mengembalikan `403`, begitu juga dengan kunci dari aplikasi lain, kunci dengan cakupan tanpa izin yang dibutuhkan endpoint ini, dan permintaan dari luar daftar izin IP kunci tersebut; kunci yang salah, dicabut, atau kedaluwarsa mengembalikan `401`. Bedakan kegagalan tersebut berdasarkan `detail`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "Pesan kesalahan yang mudah dibaca manusia."
                    }
                  }
                },
                "examples": {
                  "Missing or invalid credentials": {
                    "summary": "Tidak ada header x-api-key, atau kunci gagal divalidasi",
                    "value": {
                      "detail": "Authentication credentials were not provided or are invalid."
                    }
                  },
                  "Other application": {
                    "summary": "Kunci valid milik aplikasi yang berbeda dari sesi",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Scoped key without decisions write": {
                    "summary": "Kunci ber-scope tidak memiliki decisions: write",
                    "value": {
                      "detail": "This API key has no write access to decisions."
                    }
                  },
                  "IP not allowed": {
                    "summary": "Permintaan dari luar daftar izin IP kunci",
                    "value": {
                      "detail": "This API key can't be used from this IP address."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Sesi tidak ada, telah dihapus, milik aplikasi lain, atau berada di luar batas kunci dengan cakupan terbatas; tidak ada detail yang membedakannya.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "Pesan kesalahan yang mudah dibaca manusia."
                    }
                  }
                },
                "example": {
                  "detail": "Session not found."
                }
              }
            }
          },
          "409": {
            "description": "Sesi telah selesai (`kyb_session_not_writable`) atau tidak berada pada langkah Dokumen KYB (`kyb_step_mismatch`, dengan `next_step` menyebutkan langkah tempat sesi tersebut berada).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "Pesan kesalahan yang mudah dibaca manusia."
                    },
                    "code": {
                      "type": "string"
                    },
                    "next_step": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "detail": "The session is not on the step this operation completes.",
                  "code": "kyb_step_mismatch",
                  "next_step": "KYB_REGISTRY"
                }
              }
            }
          },
          "429": {
            "description": "Batas laju terlampaui: 300 permintaan penulisan (POST, PATCH, DELETE) per menit per kunci API. Tunggu selama `Retry-After` detik sebelum mencoba lagi; header `X-RateLimit-*` menunjukkan anggaran tersebut.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "Pesan kesalahan yang mudah dibaca manusia."
                    }
                  }
                },
                "examples": {
                  "Rate limited": {
                    "summary": "Anggaran untuk menit saat ini habis",
                    "value": {
                      "detail": "Write request rate limit exceeded. You can make up to 300 requests per minute."
                    }
                  }
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Detik untuk menunggu sebelum mencoba lagi.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "example": 30
                }
              }
            }
          },
          "503": {
            "$ref": "#/components/responses/DocumentProcessingBusy"
          }
        },
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.upload_kyb_documents(\n    \"33333333-4444-5555-6666-777777777777\",\n    documents=[open(\"document.pdf\", \"rb\")],\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit, { fileFromPath } from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.uploadKybDocuments(\"33333333-4444-5555-6666-777777777777\", {\n  documents: [await fileFromPath(\"document.pdf\")],\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.UploadKYBDocuments(ctx, \"33333333-4444-5555-6666-777777777777\", didit.SessionsUploadKYBDocumentsParams{\n\tDocuments: []didit.File{didit.FileFromPath(\"document.pdf\")},\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.nio.file.Path;\nimport java.util.List;\nimport me.didit.Didit;\nimport me.didit.types.SessionsUploadKybDocumentsParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().uploadKybDocuments(\"33333333-4444-5555-6666-777777777777\", SessionsUploadKybDocumentsParams.builder()\n        .documents(List.of(Path.of(\"document.pdf\")))\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\nuse Didit\\File;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->sessions->uploadKybDocuments('33333333-4444-5555-6666-777777777777', [\n    'documents' => [File::fromPath('document.pdf')],\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.upload_kyb_documents(\n  \"33333333-4444-5555-6666-777777777777\",\n  documents: [Pathname(\"document.pdf\")]\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.UploadKybDocumentsAsync(\"33333333-4444-5555-6666-777777777777\", new SessionsUploadKybDocumentsParams\n{\n    Documents = new FileUpload[] { FileUpload.FromPath(\"document.pdf\") },\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/session/{sessionId}/kyb/extracted-parties/": {
      "get": {
        "summary": "Daftar pihak yang disebutkan oleh dokumen yang diunggah",
        "description": "Mengembalikan pemegang saham dan direktur yang disebutkan dalam dokumen yang diunggah ke sesi KYB ini, digabungkan per orang dan diatribusikan ke dokumen yang menyebutkannya. Tampilkan kepada pemohon Anda untuk dikonfirmasi, lalu deklarasikan dengan endpoint draf pihak. Rentang tetap berupa rentang: `ownership_percent.text` mempertahankan angka apa adanya dan `min` / `max` angka yang dibaca darinya. Tidak ada yang dilabeli sebagai UBO di sini; hal tersebut ditentukan saat pihak-pihak dikirimkan, berdasarkan pengaturan peran dan ambang batas kepemilikan pada alur kerja. Daftar yang sama ada dalam keputusan sesi sebagai `document_verifications[].extracted_parties`. Memerlukan `read:businesses` atau `read:sessions`.",
        "operationId": "get_v3_session_kyb_extracted_parties",
        "x-didit-sdk": {
          "resource": "sessions",
          "method": "list_kyb_extracted_parties",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Sessions"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "sessionId",
            "in": "path",
            "required": true,
            "description": "UUID dari sesi Verifikasi Bisnis (KYB). UUID ini harus dimiliki oleh aplikasi yang terkait dengan kunci API.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "33333333-4444-5555-6666-777777777777"
            }
          },
          {
            "name": "node_id",
            "in": "query",
            "required": false,
            "description": "Node alur kerja dari langkah KYB. Hanya diperlukan jika alur kerja memiliki lebih dari satu node KYB; secara default Didit menggunakan node milik sesi itu sendiri.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Pihak yang disebutkan dalam dokumen saat ini.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "parties",
                    "document_count"
                  ],
                  "properties": {
                    "parties": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "name": {
                            "type": "string"
                          },
                          "entity_type": {
                            "type": "string",
                            "enum": [
                              "person",
                              "company"
                            ]
                          },
                          "first_name": {
                            "type": "string",
                            "nullable": true
                          },
                          "last_name": {
                            "type": "string",
                            "nullable": true
                          },
                          "appointment_date": {
                            "type": "string",
                            "nullable": true
                          },
                          "designation": {
                            "type": "string",
                            "nullable": true
                          },
                          "roles": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "role": {
                                  "type": "string",
                                  "enum": [
                                    "director",
                                    "non_executive_director",
                                    "secretary",
                                    "chairman",
                                    "ubo",
                                    "shareholder",
                                    "representative",
                                    "founder",
                                    "legal_advisor",
                                    "authorized_signatory",
                                    "trustee",
                                    "beneficiary",
                                    "settlor",
                                    "protector",
                                    "company_officer",
                                    "investor",
                                    "other"
                                  ]
                                },
                                "ownership_percent": {
                                  "type": "object",
                                  "properties": {
                                    "text": {
                                      "type": "string",
                                      "nullable": true,
                                      "description": "Angka kepemilikan persis seperti yang tertera dalam dokumen, seperti `25-50%`, `>50%`, atau `NO EXHIBE`."
                                    },
                                    "min": {
                                      "type": "number",
                                      "nullable": true,
                                      "description": "Angka lebih rendah yang dibaca dari `text`; null jika tidak menyatakan apa pun."
                                    },
                                    "max": {
                                      "type": "number",
                                      "nullable": true,
                                      "description": "Angka atas yang dibaca dari `text`; null jika tidak menyatakan apa pun."
                                    }
                                  }
                                }
                              }
                            }
                          },
                          "documents": {
                            "type": "array",
                            "description": "Dokumen yang diunggah yang menyebutkan pihak ini.",
                            "items": {
                              "type": "object",
                              "properties": {
                                "document_uuid": {
                                  "type": "string",
                                  "format": "uuid"
                                },
                                "document_type": {
                                  "type": "string",
                                  "nullable": true
                                },
                                "document_subtype": {
                                  "type": "string",
                                  "nullable": true
                                },
                                "original_filename": {
                                  "type": "string",
                                  "nullable": true
                                },
                                "status": {
                                  "type": "string",
                                  "nullable": true
                                }
                              }
                            }
                          }
                        }
                      },
                      "description": "Pemegang saham dan direktur yang disebutkan dalam dokumen yang diunggah, digabungkan per orang. Tidak ada yang dilabeli sebagai UBO di sini: hal tersebut diputuskan ketika para pihak diajukan."
                    },
                    "document_count": {
                      "type": "integer",
                      "description": "Jumlah dokumen yang diunggah yang menjadi sumber daftar tersebut."
                    },
                    "node_id": {
                      "type": "string",
                      "nullable": true
                    }
                  }
                },
                "example": {
                  "parties": [
                    {
                      "name": "Ana Lopez",
                      "entity_type": "person",
                      "first_name": "Ana",
                      "last_name": "Lopez",
                      "appointment_date": null,
                      "designation": "Administrador unico",
                      "roles": [
                        {
                          "role": "shareholder",
                          "ownership_percent": {
                            "text": "60%",
                            "min": 60,
                            "max": 60
                          }
                        }
                      ],
                      "documents": [
                        {
                          "document_uuid": "0a3f1e2c-7c2f-4a1b-9d55-2f8d2a5d6b41",
                          "document_type": "OWNERSHIP_STRUCTURE",
                          "document_subtype": "ARTICLES_OF_INCORPORATION",
                          "original_filename": "acta_constitutiva.pdf",
                          "status": "Approved"
                        }
                      ]
                    }
                  ],
                  "document_count": 1,
                  "node_id": "node_kyb_documents"
                }
              }
            }
          },
          "401": {
            "description": "Kunci API dengan cakupan terbatas telah kedaluwarsa. Ini satu-satunya kasus yang mengembalikan `401`: kunci yang hilang, tidak valid, atau dicabut mengembalikan `403`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "Pesan kesalahan yang mudah dibaca manusia."
                    }
                  }
                },
                "examples": {
                  "Expired key": {
                    "summary": "Tanggal kedaluwarsa kunci telah lewat",
                    "value": {
                      "detail": "This API key has expired."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Kegagalan autentikasi atau otorisasi. Kunci yang hilang mengembalikan `403`, begitu juga dengan kunci dari aplikasi lain, kunci dengan cakupan tanpa izin yang dibutuhkan endpoint ini, dan permintaan dari luar daftar izin IP kunci tersebut; kunci yang salah, dicabut, atau kedaluwarsa mengembalikan `401`. Bedakan kegagalan tersebut berdasarkan `detail`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "Pesan kesalahan yang mudah dibaca manusia."
                    }
                  }
                },
                "examples": {
                  "Missing or invalid credentials": {
                    "summary": "Tidak ada header x-api-key, atau kunci gagal divalidasi",
                    "value": {
                      "detail": "Authentication credentials were not provided or are invalid."
                    }
                  },
                  "Other application": {
                    "summary": "Kunci valid milik aplikasi yang berbeda dari sesi",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Scoped key without decisions write": {
                    "summary": "Kunci ber-scope tidak memiliki decisions: write",
                    "value": {
                      "detail": "This API key has no write access to decisions."
                    }
                  },
                  "IP not allowed": {
                    "summary": "Permintaan dari luar daftar izin IP kunci",
                    "value": {
                      "detail": "This API key can't be used from this IP address."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Sesi tidak ada, telah dihapus, milik aplikasi lain, atau berada di luar batas kunci dengan cakupan terbatas; tidak ada detail yang membedakannya.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "Pesan kesalahan yang mudah dibaca manusia."
                    }
                  }
                },
                "example": {
                  "detail": "Session not found."
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.list_kyb_extracted_parties(\n    \"33333333-4444-5555-6666-777777777777\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.listKybExtractedParties(\"33333333-4444-5555-6666-777777777777\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.ListKYBExtractedParties(ctx, \"33333333-4444-5555-6666-777777777777\", didit.SessionsListKYBExtractedPartiesParams{})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().listKybExtractedParties(\"33333333-4444-5555-6666-777777777777\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->sessions->listKybExtractedParties('33333333-4444-5555-6666-777777777777');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.list_kyb_extracted_parties(\"33333333-4444-5555-6666-777777777777\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.ListKybExtractedPartiesAsync(\"33333333-4444-5555-6666-777777777777\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/session/{sessionId}/kyb/parties/drafts/": {
      "get": {
        "summary": "Mencantumkan daftar draf pihak KYB",
        "description": "Daftar pihak yang sedang Anda siapkan untuk sesi KYB ini, yang terlama terlebih dahulu. Draf bukan merupakan pihak yang dideklarasikan: draf tidak muncul dalam keputusan atau konsol dan tidak membuat sesi verifikasi hingga Anda mengirimkannya dengan `POST /v3/session/{sessionId}/kyb/parties/submit/`. Memerlukan `write:businesses`.",
        "operationId": "get_v3_session_kyb_party_drafts",
        "x-didit-sdk": {
          "resource": "sessions",
          "method": "list_kyb_party_drafts",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Sessions"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "sessionId",
            "in": "path",
            "required": true,
            "description": "UUID dari sesi Verifikasi Bisnis (KYB). UUID ini harus dimiliki oleh aplikasi yang terkait dengan kunci API.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "33333333-4444-5555-6666-777777777777"
            }
          },
          {
            "name": "node_id",
            "in": "query",
            "required": false,
            "description": "Node alur kerja dari langkah KYB. Hanya diperlukan jika alur kerja memiliki lebih dari satu node KYB; secara default Didit menggunakan node milik sesi itu sendiri.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Draf yang tersimpan.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "parties": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "required": [
                          "draft_id",
                          "created_at",
                          "updated_at",
                          "party"
                        ],
                        "properties": {
                          "draft_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "created_at": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "updated_at": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "party": {
                            "type": "object",
                            "required": [
                              "entity_type",
                              "nationality"
                            ],
                            "properties": {
                              "entity_type": {
                                "type": "string",
                                "enum": [
                                  "person",
                                  "company"
                                ],
                                "description": "Apakah pihak tersebut adalah individu atau perusahaan."
                              },
                              "full_name": {
                                "type": "string",
                                "maxLength": 255,
                                "description": "Nama lengkap seseorang. Kirimkan ini, atau `first_name` dan `last_name`."
                              },
                              "first_name": {
                                "type": "string",
                                "maxLength": 128
                              },
                              "last_name": {
                                "type": "string",
                                "maxLength": 128
                              },
                              "role": {
                                "type": "string",
                                "enum": [
                                  "director",
                                  "non_executive_director",
                                  "secretary",
                                  "chairman",
                                  "ubo",
                                  "shareholder",
                                  "representative",
                                  "founder",
                                  "legal_advisor",
                                  "authorized_signatory",
                                  "trustee",
                                  "beneficiary",
                                  "settlor",
                                  "protector",
                                  "company_officer",
                                  "investor",
                                  "other"
                                ],
                                "description": "Peran yang dipegang oleh pihak terkait. Dapat dipertukarkan dengan `roles`; saat keduanya dikirim, keduanya digabungkan."
                              },
                              "roles": {
                                "type": "array",
                                "items": {
                                  "type": "string",
                                  "enum": [
                                    "director",
                                    "non_executive_director",
                                    "secretary",
                                    "chairman",
                                    "ubo",
                                    "shareholder",
                                    "representative",
                                    "founder",
                                    "legal_advisor",
                                    "authorized_signatory",
                                    "trustee",
                                    "beneficiary",
                                    "settlor",
                                    "protector",
                                    "company_officer",
                                    "investor",
                                    "other"
                                  ]
                                },
                                "description": "Setiap peran yang dipegang pihak tersebut. Seseorang memerlukan setidaknya satu peran (di sini atau di `role`)."
                              },
                              "position": {
                                "type": "string",
                                "maxLength": 128,
                                "description": "Jabatan seseorang."
                              },
                              "date_of_birth": {
                                "type": "string",
                                "format": "date",
                                "nullable": true
                              },
                              "company_name": {
                                "type": "string",
                                "maxLength": 255,
                                "description": "Nama pihak perusahaan. Wajib jika `entity_type` bernilai `company`."
                              },
                              "registration_number": {
                                "type": "string",
                                "maxLength": 100,
                                "description": "Nomor registrasi dari pihak perusahaan."
                              },
                              "email": {
                                "type": "string",
                                "format": "email",
                                "description": "Tujuan pengiriman tautan verifikasi. Wajib diisi jika pihak tersebut harus menyelesaikan verifikasi, yang bergantung pada pengaturan peran dan ambang batas kepemilikan alur kerja."
                              },
                              "ownership_percent": {
                                "type": "number",
                                "nullable": true,
                                "description": "Porsi kepemilikan pihak tersebut di dalam perusahaan."
                              },
                              "nationality": {
                                "type": "string",
                                "maxLength": 100,
                                "description": "Kewarganegaraan seseorang, atau negara pendirian perusahaan. Wajib untuk setiap pihak."
                              },
                              "phone_number": {
                                "type": "string",
                                "maxLength": 32
                              },
                              "custom_fields": {
                                "type": "object",
                                "additionalProperties": true,
                                "description": "Kolom tambahan yang ditentukan alur kerja."
                              },
                              "skip_verification": {
                                "type": "boolean",
                                "default": false,
                                "description": "Minta untuk melewati verifikasi pihak ini. Hanya dipenuhi jika peran pihak tersebut mengizinkan pelewatan dalam pengaturan Pihak Kunci alur kerja."
                              }
                            }
                          }
                        }
                      }
                    },
                    "node_id": {
                      "type": "string",
                      "nullable": true
                    }
                  }
                },
                "example": {
                  "parties": [
                    {
                      "draft_id": "5b0d7a52-9d3e-4f0c-8c6a-0e5f3a1b2c4d",
                      "created_at": "2026-10-31T10:00:00Z",
                      "updated_at": "2026-10-31T10:00:00Z",
                      "party": {
                        "entity_type": "person",
                        "first_name": "Ana",
                        "last_name": "Lopez",
                        "roles": [
                          "ubo",
                          "director"
                        ],
                        "ownership_percent": 60,
                        "nationality": "MEX",
                        "email": "ana.lopez@example.com",
                        "date_of_birth": "1984-06-12"
                      }
                    }
                  ],
                  "node_id": "node_kyb_key_people"
                }
              }
            }
          },
          "401": {
            "description": "Kunci API dengan cakupan terbatas telah kedaluwarsa. Ini satu-satunya kasus yang mengembalikan `401`: kunci yang hilang, tidak valid, atau dicabut mengembalikan `403`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "Pesan kesalahan yang mudah dibaca manusia."
                    }
                  }
                },
                "examples": {
                  "Expired key": {
                    "summary": "Tanggal kedaluwarsa kunci telah lewat",
                    "value": {
                      "detail": "This API key has expired."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Kegagalan autentikasi atau otorisasi. Kunci yang hilang mengembalikan `403`, begitu juga dengan kunci dari aplikasi lain, kunci dengan cakupan tanpa izin yang dibutuhkan endpoint ini, dan permintaan dari luar daftar izin IP kunci tersebut; kunci yang salah, dicabut, atau kedaluwarsa mengembalikan `401`. Bedakan kegagalan tersebut berdasarkan `detail`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "Pesan kesalahan yang mudah dibaca manusia."
                    }
                  }
                },
                "examples": {
                  "Missing or invalid credentials": {
                    "summary": "Tidak ada header x-api-key, atau kunci gagal divalidasi",
                    "value": {
                      "detail": "Authentication credentials were not provided or are invalid."
                    }
                  },
                  "Other application": {
                    "summary": "Kunci valid milik aplikasi yang berbeda dari sesi",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Scoped key without decisions write": {
                    "summary": "Kunci ber-scope tidak memiliki decisions: write",
                    "value": {
                      "detail": "This API key has no write access to decisions."
                    }
                  },
                  "IP not allowed": {
                    "summary": "Permintaan dari luar daftar izin IP kunci",
                    "value": {
                      "detail": "This API key can't be used from this IP address."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Sesi tidak ada, telah dihapus, milik aplikasi lain, atau berada di luar batas kunci dengan cakupan terbatas; tidak ada detail yang membedakannya.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "Pesan kesalahan yang mudah dibaca manusia."
                    }
                  }
                },
                "example": {
                  "detail": "Session not found."
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.list_kyb_party_drafts(\n    \"33333333-4444-5555-6666-777777777777\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.listKybPartyDrafts(\"33333333-4444-5555-6666-777777777777\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.ListKYBPartyDrafts(ctx, \"33333333-4444-5555-6666-777777777777\", didit.SessionsListKYBPartyDraftsParams{})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().listKybPartyDrafts(\"33333333-4444-5555-6666-777777777777\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->sessions->listKybPartyDrafts('33333333-4444-5555-6666-777777777777');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.list_kyb_party_drafts(\"33333333-4444-5555-6666-777777777777\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.ListKybPartyDraftsAsync(\"33333333-4444-5555-6666-777777777777\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      },
      "post": {
        "summary": "Buat draf pihak KYB",
        "description": "Tambahkan pihak (individu atau perusahaan) ke daftar yang sedang Anda siapkan untuk sesi KYB ini. Kolom dan aturan yang sama seperti layar Pihak Kunci yang di-hosting berlaku: individu memerlukan `full_name` atau `first_name` dan `last_name`, setidaknya satu peran, dan kewarganegaraan; perusahaan memerlukan `company_name` dan negara pendirian di `nationality`. Tidak ada yang dideklarasikan atau ditagihkan hingga `POST /v3/session/{sessionId}/kyb/parties/submit/`. Memerlukan `write:businesses`.",
        "operationId": "post_v3_session_kyb_party_drafts",
        "x-didit-sdk": {
          "resource": "sessions",
          "method": "create_kyb_party_draft",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Sessions"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "sessionId",
            "in": "path",
            "required": true,
            "description": "UUID dari sesi Verifikasi Bisnis (KYB). UUID ini harus dimiliki oleh aplikasi yang terkait dengan kunci API.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "33333333-4444-5555-6666-777777777777"
            }
          },
          {
            "name": "node_id",
            "in": "query",
            "required": false,
            "description": "Node alur kerja dari langkah KYB. Hanya diperlukan jika alur kerja memiliki lebih dari satu node KYB; secara default Didit menggunakan node milik sesi itu sendiri.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "entity_type",
                  "nationality"
                ],
                "properties": {
                  "entity_type": {
                    "type": "string",
                    "enum": [
                      "person",
                      "company"
                    ],
                    "description": "Apakah pihak tersebut adalah individu atau perusahaan."
                  },
                  "full_name": {
                    "type": "string",
                    "maxLength": 255,
                    "description": "Nama lengkap seseorang. Kirimkan ini, atau `first_name` dan `last_name`."
                  },
                  "first_name": {
                    "type": "string",
                    "maxLength": 128
                  },
                  "last_name": {
                    "type": "string",
                    "maxLength": 128
                  },
                  "role": {
                    "type": "string",
                    "enum": [
                      "director",
                      "non_executive_director",
                      "secretary",
                      "chairman",
                      "ubo",
                      "shareholder",
                      "representative",
                      "founder",
                      "legal_advisor",
                      "authorized_signatory",
                      "trustee",
                      "beneficiary",
                      "settlor",
                      "protector",
                      "company_officer",
                      "investor",
                      "other"
                    ],
                    "description": "Peran yang dipegang oleh pihak terkait. Dapat dipertukarkan dengan `roles`; saat keduanya dikirim, keduanya digabungkan."
                  },
                  "roles": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "enum": [
                        "director",
                        "non_executive_director",
                        "secretary",
                        "chairman",
                        "ubo",
                        "shareholder",
                        "representative",
                        "founder",
                        "legal_advisor",
                        "authorized_signatory",
                        "trustee",
                        "beneficiary",
                        "settlor",
                        "protector",
                        "company_officer",
                        "investor",
                        "other"
                      ]
                    },
                    "description": "Setiap peran yang dipegang pihak tersebut. Seseorang memerlukan setidaknya satu peran (di sini atau di `role`)."
                  },
                  "position": {
                    "type": "string",
                    "maxLength": 128,
                    "description": "Jabatan seseorang."
                  },
                  "date_of_birth": {
                    "type": "string",
                    "format": "date",
                    "nullable": true
                  },
                  "company_name": {
                    "type": "string",
                    "maxLength": 255,
                    "description": "Nama pihak perusahaan. Wajib jika `entity_type` bernilai `company`."
                  },
                  "registration_number": {
                    "type": "string",
                    "maxLength": 100,
                    "description": "Nomor registrasi dari pihak perusahaan."
                  },
                  "email": {
                    "type": "string",
                    "format": "email",
                    "description": "Tujuan pengiriman tautan verifikasi. Wajib diisi jika pihak tersebut harus menyelesaikan verifikasi, yang bergantung pada pengaturan peran dan ambang batas kepemilikan alur kerja."
                  },
                  "ownership_percent": {
                    "type": "number",
                    "nullable": true,
                    "description": "Porsi kepemilikan pihak tersebut di dalam perusahaan."
                  },
                  "nationality": {
                    "type": "string",
                    "maxLength": 100,
                    "description": "Kewarganegaraan seseorang, atau negara pendirian perusahaan. Wajib untuk setiap pihak."
                  },
                  "phone_number": {
                    "type": "string",
                    "maxLength": 32
                  },
                  "custom_fields": {
                    "type": "object",
                    "additionalProperties": true,
                    "description": "Kolom tambahan yang ditentukan alur kerja."
                  },
                  "skip_verification": {
                    "type": "boolean",
                    "default": false,
                    "description": "Minta untuk melewati verifikasi pihak ini. Hanya dipenuhi jika peran pihak tersebut mengizinkan pelewatan dalam pengaturan Pihak Kunci alur kerja."
                  }
                }
              },
              "example": {
                "entity_type": "person",
                "first_name": "Ana",
                "last_name": "Lopez",
                "roles": [
                  "ubo",
                  "director"
                ],
                "ownership_percent": 60,
                "nationality": "MEX",
                "email": "ana.lopez@example.com",
                "date_of_birth": "1984-06-12"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Draf berhasil dibuat.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "draft_id",
                    "created_at",
                    "updated_at",
                    "party"
                  ],
                  "properties": {
                    "draft_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "created_at": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "updated_at": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "party": {
                      "type": "object",
                      "required": [
                        "entity_type",
                        "nationality"
                      ],
                      "properties": {
                        "entity_type": {
                          "type": "string",
                          "enum": [
                            "person",
                            "company"
                          ],
                          "description": "Apakah pihak tersebut adalah individu atau perusahaan."
                        },
                        "full_name": {
                          "type": "string",
                          "maxLength": 255,
                          "description": "Nama lengkap seseorang. Kirimkan ini, atau `first_name` dan `last_name`."
                        },
                        "first_name": {
                          "type": "string",
                          "maxLength": 128
                        },
                        "last_name": {
                          "type": "string",
                          "maxLength": 128
                        },
                        "role": {
                          "type": "string",
                          "enum": [
                            "director",
                            "non_executive_director",
                            "secretary",
                            "chairman",
                            "ubo",
                            "shareholder",
                            "representative",
                            "founder",
                            "legal_advisor",
                            "authorized_signatory",
                            "trustee",
                            "beneficiary",
                            "settlor",
                            "protector",
                            "company_officer",
                            "investor",
                            "other"
                          ],
                          "description": "Peran yang dipegang oleh pihak terkait. Dapat dipertukarkan dengan `roles`; saat keduanya dikirim, keduanya digabungkan."
                        },
                        "roles": {
                          "type": "array",
                          "items": {
                            "type": "string",
                            "enum": [
                              "director",
                              "non_executive_director",
                              "secretary",
                              "chairman",
                              "ubo",
                              "shareholder",
                              "representative",
                              "founder",
                              "legal_advisor",
                              "authorized_signatory",
                              "trustee",
                              "beneficiary",
                              "settlor",
                              "protector",
                              "company_officer",
                              "investor",
                              "other"
                            ]
                          },
                          "description": "Setiap peran yang dipegang pihak tersebut. Seseorang memerlukan setidaknya satu peran (di sini atau di `role`)."
                        },
                        "position": {
                          "type": "string",
                          "maxLength": 128,
                          "description": "Jabatan seseorang."
                        },
                        "date_of_birth": {
                          "type": "string",
                          "format": "date",
                          "nullable": true
                        },
                        "company_name": {
                          "type": "string",
                          "maxLength": 255,
                          "description": "Nama pihak perusahaan. Wajib jika `entity_type` bernilai `company`."
                        },
                        "registration_number": {
                          "type": "string",
                          "maxLength": 100,
                          "description": "Nomor registrasi dari pihak perusahaan."
                        },
                        "email": {
                          "type": "string",
                          "format": "email",
                          "description": "Tujuan pengiriman tautan verifikasi. Wajib diisi jika pihak tersebut harus menyelesaikan verifikasi, yang bergantung pada pengaturan peran dan ambang batas kepemilikan alur kerja."
                        },
                        "ownership_percent": {
                          "type": "number",
                          "nullable": true,
                          "description": "Porsi kepemilikan pihak tersebut di dalam perusahaan."
                        },
                        "nationality": {
                          "type": "string",
                          "maxLength": 100,
                          "description": "Kewarganegaraan seseorang, atau negara pendirian perusahaan. Wajib untuk setiap pihak."
                        },
                        "phone_number": {
                          "type": "string",
                          "maxLength": 32
                        },
                        "custom_fields": {
                          "type": "object",
                          "additionalProperties": true,
                          "description": "Kolom tambahan yang ditentukan alur kerja."
                        },
                        "skip_verification": {
                          "type": "boolean",
                          "default": false,
                          "description": "Minta untuk melewati verifikasi pihak ini. Hanya dipenuhi jika peran pihak tersebut mengizinkan pelewatan dalam pengaturan Pihak Kunci alur kerja."
                        }
                      }
                    }
                  }
                },
                "example": {
                  "draft_id": "5b0d7a52-9d3e-4f0c-8c6a-0e5f3a1b2c4d",
                  "created_at": "2026-10-31T10:00:00Z",
                  "updated_at": "2026-10-31T10:00:00Z",
                  "party": {
                    "entity_type": "person",
                    "first_name": "Ana",
                    "last_name": "Lopez",
                    "roles": [
                      "ubo",
                      "director"
                    ],
                    "ownership_percent": 60,
                    "nationality": "MEX",
                    "email": "ana.lopez@example.com",
                    "date_of_birth": "1984-06-12"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Kolom pihak tidak valid atau kolom wajib tidak ada.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "Pesan kesalahan yang mudah dibaca manusia."
                    }
                  }
                },
                "example": {
                  "non_field_errors": [
                    "Person parties require at least one role."
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Kunci API dengan cakupan terbatas telah kedaluwarsa. Ini satu-satunya kasus yang mengembalikan `401`: kunci yang hilang, tidak valid, atau dicabut mengembalikan `403`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "Pesan kesalahan yang mudah dibaca manusia."
                    }
                  }
                },
                "examples": {
                  "Expired key": {
                    "summary": "Tanggal kedaluwarsa kunci telah lewat",
                    "value": {
                      "detail": "This API key has expired."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Kegagalan autentikasi atau otorisasi. Kunci yang hilang mengembalikan `403`, begitu juga dengan kunci dari aplikasi lain, kunci dengan cakupan tanpa izin yang dibutuhkan endpoint ini, dan permintaan dari luar daftar izin IP kunci tersebut; kunci yang salah, dicabut, atau kedaluwarsa mengembalikan `401`. Bedakan kegagalan tersebut berdasarkan `detail`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "Pesan kesalahan yang mudah dibaca manusia."
                    }
                  }
                },
                "examples": {
                  "Missing or invalid credentials": {
                    "summary": "Tidak ada header x-api-key, atau kunci gagal divalidasi",
                    "value": {
                      "detail": "Authentication credentials were not provided or are invalid."
                    }
                  },
                  "Other application": {
                    "summary": "Kunci valid milik aplikasi yang berbeda dari sesi",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Scoped key without decisions write": {
                    "summary": "Kunci ber-scope tidak memiliki decisions: write",
                    "value": {
                      "detail": "This API key has no write access to decisions."
                    }
                  },
                  "IP not allowed": {
                    "summary": "Permintaan dari luar daftar izin IP kunci",
                    "value": {
                      "detail": "This API key can't be used from this IP address."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Sesi tidak ada, telah dihapus, milik aplikasi lain, atau berada di luar batas kunci dengan cakupan terbatas; tidak ada detail yang membedakannya.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "Pesan kesalahan yang mudah dibaca manusia."
                    }
                  }
                },
                "example": {
                  "detail": "Session not found."
                }
              }
            }
          },
          "409": {
            "description": "Sesi telah selesai (`kyb_session_not_writable`).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "Pesan kesalahan yang mudah dibaca manusia."
                    },
                    "code": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "detail": "This verification session is no longer accepting changes.",
                  "code": "kyb_session_not_writable"
                }
              }
            }
          },
          "429": {
            "description": "Batas laju terlampaui: 300 permintaan penulisan (POST, PATCH, DELETE) per menit per kunci API. Tunggu selama `Retry-After` detik sebelum mencoba lagi; header `X-RateLimit-*` menunjukkan anggaran tersebut.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "Pesan kesalahan yang mudah dibaca manusia."
                    }
                  }
                },
                "examples": {
                  "Rate limited": {
                    "summary": "Anggaran untuk menit saat ini habis",
                    "value": {
                      "detail": "Write request rate limit exceeded. You can make up to 300 requests per minute."
                    }
                  }
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Detik untuk menunggu sebelum mencoba lagi.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "example": 30
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.create_kyb_party_draft(\n    \"33333333-4444-5555-6666-777777777777\",\n    entity_type=\"person\",\n    first_name=\"Ana\",\n    last_name=\"Lopez\",\n    roles=[\"ubo\", \"director\"],\n    date_of_birth=\"1984-06-12\",\n    email=\"ana.lopez@example.com\",\n    ownership_percent=60.0,\n    nationality=\"MEX\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.createKybPartyDraft(\"33333333-4444-5555-6666-777777777777\", {\n  entity_type: \"person\",\n  first_name: \"Ana\",\n  last_name: \"Lopez\",\n  roles: [\"ubo\", \"director\"],\n  date_of_birth: \"1984-06-12\",\n  email: \"ana.lopez@example.com\",\n  ownership_percent: 60.0,\n  nationality: \"MEX\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.CreateKYBPartyDraft(ctx, \"33333333-4444-5555-6666-777777777777\", didit.SessionsCreateKYBPartyDraftParams{\n\tEntityType:       \"person\",\n\tFirstName:        didit.String(\"Ana\"),\n\tLastName:         didit.String(\"Lopez\"),\n\tRoles:            didit.Some([]didit.SessionsCreateKYBPartyDraftParamsRoles{\"ubo\", \"director\"}),\n\tDateOfBirth:      didit.String(\"1984-06-12\"),\n\tEmail:            didit.String(\"ana.lopez@example.com\"),\n\tOwnershipPercent: didit.Float(60.0),\n\tNationality:      \"MEX\",\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import java.time.LocalDate;\nimport java.util.List;\nimport me.didit.Didit;\nimport me.didit.types.SessionsCreateKybPartyDraftParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().createKybPartyDraft(\"33333333-4444-5555-6666-777777777777\", SessionsCreateKybPartyDraftParams.builder()\n        .entityType(SessionsCreateKybPartyDraftParams.EntityType.of(\"person\"))\n        .firstName(\"Ana\")\n        .lastName(\"Lopez\")\n        .roles(List.of(SessionsCreateKybPartyDraftParams.Roles.of(\"ubo\"), SessionsCreateKybPartyDraftParams.Roles.of(\"director\")))\n        .dateOfBirth(LocalDate.parse(\"1984-06-12\"))\n        .email(\"ana.lopez@example.com\")\n        .ownershipPercent(60.0)\n        .nationality(\"MEX\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->sessions->createKybPartyDraft('33333333-4444-5555-6666-777777777777', [\n    'entity_type' => 'person',\n    'first_name' => 'Ana',\n    'last_name' => 'Lopez',\n    'roles' => ['ubo', 'director'],\n    'date_of_birth' => '1984-06-12',\n    'email' => 'ana.lopez@example.com',\n    'ownership_percent' => 60.0,\n    'nationality' => 'MEX',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.create_kyb_party_draft(\n  \"33333333-4444-5555-6666-777777777777\",\n  entity_type: \"person\",\n  first_name: \"Ana\",\n  last_name: \"Lopez\",\n  roles: [\"ubo\", \"director\"],\n  date_of_birth: \"1984-06-12\",\n  email: \"ana.lopez@example.com\",\n  ownership_percent: 60.0,\n  nationality: \"MEX\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.CreateKybPartyDraftAsync(\"33333333-4444-5555-6666-777777777777\", new SessionsCreateKybPartyDraftParams\n{\n    EntityType = \"person\",\n    FirstName = \"Ana\",\n    LastName = \"Lopez\",\n    Roles = new SessionsCreateKybPartyDraftParamsRoles[] { \"ubo\", \"director\" },\n    DateOfBirth = \"1984-06-12\",\n    Email = \"ana.lopez@example.com\",\n    OwnershipPercent = 60.0,\n    Nationality = \"MEX\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/session/{sessionId}/kyb/parties/drafts/{draftId}/": {
      "patch": {
        "summary": "Edit draf pihak KYB",
        "description": "Ubah kolom dari satu draf pihak. Pengeditan digabungkan ke dalam draf yang disimpan dan pihak yang digabungkan divalidasi secara keseluruhan, sehingga pengeditan yang akan membuat pihak tersebut tidak lengkap akan ditolak. Mengubah `first_name` atau `last_name` akan menggantikan nama lengkap yang disimpan. Memerlukan `write:businesses`.",
        "operationId": "patch_v3_session_kyb_party_draft",
        "x-didit-sdk": {
          "resource": "sessions",
          "method": "update_kyb_party_draft",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Sessions"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "sessionId",
            "in": "path",
            "required": true,
            "description": "UUID dari sesi Verifikasi Bisnis (KYB). UUID ini harus dimiliki oleh aplikasi yang terkait dengan kunci API.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "33333333-4444-5555-6666-777777777777"
            }
          },
          {
            "name": "draftId",
            "in": "path",
            "required": true,
            "description": "UUID draf pihak (`draft_id` yang dikembalikan saat dibuat).",
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "5b0d7a52-9d3e-4f0c-8c6a-0e5f3a1b2c4d"
            }
          },
          {
            "name": "node_id",
            "in": "query",
            "required": false,
            "description": "Node alur kerja dari langkah KYB. Hanya diperlukan jika alur kerja memiliki lebih dari satu node KYB; secara default Didit menggunakan node milik sesi itu sendiri.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "description": "Subset apa pun dari kolom pihak. Pengeditan digabungkan ke dalam draf yang disimpan dan pihak yang digabungkan divalidasi secara keseluruhan, sehingga draf yang dapat dikirimkan sebelum pengeditan tetap dapat dikirimkan setelahnya.",
                "properties": {
                  "entity_type": {
                    "type": "string",
                    "enum": [
                      "person",
                      "company"
                    ],
                    "description": "Apakah pihak tersebut adalah individu atau perusahaan."
                  },
                  "full_name": {
                    "type": "string",
                    "maxLength": 255,
                    "description": "Nama lengkap seseorang. Kirimkan ini, atau `first_name` dan `last_name`."
                  },
                  "first_name": {
                    "type": "string",
                    "maxLength": 128
                  },
                  "last_name": {
                    "type": "string",
                    "maxLength": 128
                  },
                  "role": {
                    "type": "string",
                    "enum": [
                      "director",
                      "non_executive_director",
                      "secretary",
                      "chairman",
                      "ubo",
                      "shareholder",
                      "representative",
                      "founder",
                      "legal_advisor",
                      "authorized_signatory",
                      "trustee",
                      "beneficiary",
                      "settlor",
                      "protector",
                      "company_officer",
                      "investor",
                      "other"
                    ],
                    "description": "Peran yang dipegang oleh pihak terkait. Dapat dipertukarkan dengan `roles`; saat keduanya dikirim, keduanya digabungkan."
                  },
                  "roles": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "enum": [
                        "director",
                        "non_executive_director",
                        "secretary",
                        "chairman",
                        "ubo",
                        "shareholder",
                        "representative",
                        "founder",
                        "legal_advisor",
                        "authorized_signatory",
                        "trustee",
                        "beneficiary",
                        "settlor",
                        "protector",
                        "company_officer",
                        "investor",
                        "other"
                      ]
                    },
                    "description": "Setiap peran yang dipegang pihak tersebut. Seseorang memerlukan setidaknya satu peran (di sini atau di `role`)."
                  },
                  "position": {
                    "type": "string",
                    "maxLength": 128,
                    "description": "Jabatan seseorang."
                  },
                  "date_of_birth": {
                    "type": "string",
                    "format": "date",
                    "nullable": true
                  },
                  "company_name": {
                    "type": "string",
                    "maxLength": 255,
                    "description": "Nama pihak perusahaan. Wajib jika `entity_type` bernilai `company`."
                  },
                  "registration_number": {
                    "type": "string",
                    "maxLength": 100,
                    "description": "Nomor registrasi dari pihak perusahaan."
                  },
                  "email": {
                    "type": "string",
                    "format": "email",
                    "description": "Tujuan pengiriman tautan verifikasi. Wajib diisi jika pihak tersebut harus menyelesaikan verifikasi, yang bergantung pada pengaturan peran dan ambang batas kepemilikan alur kerja."
                  },
                  "ownership_percent": {
                    "type": "number",
                    "nullable": true,
                    "description": "Porsi kepemilikan pihak tersebut di dalam perusahaan."
                  },
                  "nationality": {
                    "type": "string",
                    "maxLength": 100,
                    "description": "Kewarganegaraan seseorang, atau negara pendirian perusahaan. Wajib untuk setiap pihak."
                  },
                  "phone_number": {
                    "type": "string",
                    "maxLength": 32
                  },
                  "custom_fields": {
                    "type": "object",
                    "additionalProperties": true,
                    "description": "Kolom tambahan yang ditentukan alur kerja."
                  },
                  "skip_verification": {
                    "type": "boolean",
                    "default": false,
                    "description": "Minta untuk melewati verifikasi pihak ini. Hanya dipenuhi jika peran pihak tersebut mengizinkan pelewatan dalam pengaturan Pihak Kunci alur kerja."
                  }
                }
              },
              "example": {
                "ownership_percent": 55
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Draf berhasil diperbarui.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "draft_id",
                    "created_at",
                    "updated_at",
                    "party"
                  ],
                  "properties": {
                    "draft_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "created_at": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "updated_at": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "party": {
                      "type": "object",
                      "required": [
                        "entity_type",
                        "nationality"
                      ],
                      "properties": {
                        "entity_type": {
                          "type": "string",
                          "enum": [
                            "person",
                            "company"
                          ],
                          "description": "Apakah pihak tersebut adalah individu atau perusahaan."
                        },
                        "full_name": {
                          "type": "string",
                          "maxLength": 255,
                          "description": "Nama lengkap seseorang. Kirimkan ini, atau `first_name` dan `last_name`."
                        },
                        "first_name": {
                          "type": "string",
                          "maxLength": 128
                        },
                        "last_name": {
                          "type": "string",
                          "maxLength": 128
                        },
                        "role": {
                          "type": "string",
                          "enum": [
                            "director",
                            "non_executive_director",
                            "secretary",
                            "chairman",
                            "ubo",
                            "shareholder",
                            "representative",
                            "founder",
                            "legal_advisor",
                            "authorized_signatory",
                            "trustee",
                            "beneficiary",
                            "settlor",
                            "protector",
                            "company_officer",
                            "investor",
                            "other"
                          ],
                          "description": "Peran yang dipegang oleh pihak terkait. Dapat dipertukarkan dengan `roles`; saat keduanya dikirim, keduanya digabungkan."
                        },
                        "roles": {
                          "type": "array",
                          "items": {
                            "type": "string",
                            "enum": [
                              "director",
                              "non_executive_director",
                              "secretary",
                              "chairman",
                              "ubo",
                              "shareholder",
                              "representative",
                              "founder",
                              "legal_advisor",
                              "authorized_signatory",
                              "trustee",
                              "beneficiary",
                              "settlor",
                              "protector",
                              "company_officer",
                              "investor",
                              "other"
                            ]
                          },
                          "description": "Setiap peran yang dipegang pihak tersebut. Seseorang memerlukan setidaknya satu peran (di sini atau di `role`)."
                        },
                        "position": {
                          "type": "string",
                          "maxLength": 128,
                          "description": "Jabatan seseorang."
                        },
                        "date_of_birth": {
                          "type": "string",
                          "format": "date",
                          "nullable": true
                        },
                        "company_name": {
                          "type": "string",
                          "maxLength": 255,
                          "description": "Nama pihak perusahaan. Wajib jika `entity_type` bernilai `company`."
                        },
                        "registration_number": {
                          "type": "string",
                          "maxLength": 100,
                          "description": "Nomor registrasi dari pihak perusahaan."
                        },
                        "email": {
                          "type": "string",
                          "format": "email",
                          "description": "Tujuan pengiriman tautan verifikasi. Wajib diisi jika pihak tersebut harus menyelesaikan verifikasi, yang bergantung pada pengaturan peran dan ambang batas kepemilikan alur kerja."
                        },
                        "ownership_percent": {
                          "type": "number",
                          "nullable": true,
                          "description": "Porsi kepemilikan pihak tersebut di dalam perusahaan."
                        },
                        "nationality": {
                          "type": "string",
                          "maxLength": 100,
                          "description": "Kewarganegaraan seseorang, atau negara pendirian perusahaan. Wajib untuk setiap pihak."
                        },
                        "phone_number": {
                          "type": "string",
                          "maxLength": 32
                        },
                        "custom_fields": {
                          "type": "object",
                          "additionalProperties": true,
                          "description": "Kolom tambahan yang ditentukan alur kerja."
                        },
                        "skip_verification": {
                          "type": "boolean",
                          "default": false,
                          "description": "Minta untuk melewati verifikasi pihak ini. Hanya dipenuhi jika peran pihak tersebut mengizinkan pelewatan dalam pengaturan Pihak Kunci alur kerja."
                        }
                      }
                    }
                  }
                },
                "example": {
                  "draft_id": "5b0d7a52-9d3e-4f0c-8c6a-0e5f3a1b2c4d",
                  "created_at": "2026-10-31T10:00:00Z",
                  "updated_at": "2026-10-31T10:00:00Z",
                  "party": {
                    "entity_type": "person",
                    "first_name": "Ana",
                    "last_name": "Lopez",
                    "roles": [
                      "ubo",
                      "director"
                    ],
                    "ownership_percent": 55,
                    "nationality": "MEX",
                    "email": "ana.lopez@example.com",
                    "date_of_birth": "1984-06-12"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Pihak yang digabungkan tidak valid.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "Pesan kesalahan yang mudah dibaca manusia."
                    }
                  }
                },
                "example": {
                  "non_field_errors": [
                    "Person parties require at least one role."
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Kunci API dengan cakupan terbatas telah kedaluwarsa. Ini satu-satunya kasus yang mengembalikan `401`: kunci yang hilang, tidak valid, atau dicabut mengembalikan `403`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "Pesan kesalahan yang mudah dibaca manusia."
                    }
                  }
                },
                "examples": {
                  "Expired key": {
                    "summary": "Tanggal kedaluwarsa kunci telah lewat",
                    "value": {
                      "detail": "This API key has expired."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Kegagalan autentikasi atau otorisasi. Kunci yang hilang mengembalikan `403`, begitu juga dengan kunci dari aplikasi lain, kunci dengan cakupan tanpa izin yang dibutuhkan endpoint ini, dan permintaan dari luar daftar izin IP kunci tersebut; kunci yang salah, dicabut, atau kedaluwarsa mengembalikan `401`. Bedakan kegagalan tersebut berdasarkan `detail`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "Pesan kesalahan yang mudah dibaca manusia."
                    }
                  }
                },
                "examples": {
                  "Missing or invalid credentials": {
                    "summary": "Tidak ada header x-api-key, atau kunci gagal divalidasi",
                    "value": {
                      "detail": "Authentication credentials were not provided or are invalid."
                    }
                  },
                  "Other application": {
                    "summary": "Kunci valid milik aplikasi yang berbeda dari sesi",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Scoped key without decisions write": {
                    "summary": "Kunci ber-scope tidak memiliki decisions: write",
                    "value": {
                      "detail": "This API key has no write access to decisions."
                    }
                  },
                  "IP not allowed": {
                    "summary": "Permintaan dari luar daftar izin IP kunci",
                    "value": {
                      "detail": "This API key can't be used from this IP address."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Sesi atau draf tidak ada, atau sesi berada di luar aplikasi yang terkait dengan kunci atau batas kunci dengan cakupan terbatas.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "Pesan kesalahan yang mudah dibaca manusia."
                    }
                  }
                },
                "example": {
                  "detail": "Session not found."
                }
              }
            }
          },
          "409": {
            "description": "Sesi telah selesai (`kyb_session_not_writable`).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "Pesan kesalahan yang mudah dibaca manusia."
                    },
                    "code": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "detail": "This verification session is no longer accepting changes.",
                  "code": "kyb_session_not_writable"
                }
              }
            }
          },
          "429": {
            "description": "Batas laju terlampaui: 300 permintaan penulisan (POST, PATCH, DELETE) per menit per kunci API. Tunggu selama `Retry-After` detik sebelum mencoba lagi; header `X-RateLimit-*` menunjukkan anggaran tersebut.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "Pesan kesalahan yang mudah dibaca manusia."
                    }
                  }
                },
                "examples": {
                  "Rate limited": {
                    "summary": "Anggaran untuk menit saat ini habis",
                    "value": {
                      "detail": "Write request rate limit exceeded. You can make up to 300 requests per minute."
                    }
                  }
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Detik untuk menunggu sebelum mencoba lagi.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "example": 30
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.update_kyb_party_draft(\n    \"33333333-4444-5555-6666-777777777777\",\n    \"5b0d7a52-9d3e-4f0c-8c6a-0e5f3a1b2c4d\",\n    ownership_percent=55.0,\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.updateKybPartyDraft(\n  \"33333333-4444-5555-6666-777777777777\",\n  \"5b0d7a52-9d3e-4f0c-8c6a-0e5f3a1b2c4d\",\n  {\n    ownership_percent: 55.0,\n  },\n);\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.UpdateKYBPartyDraft(ctx, \"33333333-4444-5555-6666-777777777777\", \"5b0d7a52-9d3e-4f0c-8c6a-0e5f3a1b2c4d\", didit.SessionsUpdateKYBPartyDraftParams{\n\tOwnershipPercent: didit.Float(55.0),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.SessionsUpdateKybPartyDraftParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().updateKybPartyDraft(\"33333333-4444-5555-6666-777777777777\", \"5b0d7a52-9d3e-4f0c-8c6a-0e5f3a1b2c4d\", SessionsUpdateKybPartyDraftParams.builder()\n        .ownershipPercent(55.0)\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->sessions->updateKybPartyDraft('33333333-4444-5555-6666-777777777777', '5b0d7a52-9d3e-4f0c-8c6a-0e5f3a1b2c4d', [\n    'ownership_percent' => 55.0,\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.update_kyb_party_draft(\n  \"33333333-4444-5555-6666-777777777777\",\n  \"5b0d7a52-9d3e-4f0c-8c6a-0e5f3a1b2c4d\",\n  ownership_percent: 55.0\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.UpdateKybPartyDraftAsync(\"33333333-4444-5555-6666-777777777777\", \"5b0d7a52-9d3e-4f0c-8c6a-0e5f3a1b2c4d\", new SessionsUpdateKybPartyDraftParams\n{\n    OwnershipPercent = 55.0,\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      },
      "delete": {
        "summary": "Hapus draf pihak KYB",
        "description": "Hapus satu draf pihak. Pihak yang dideklarasikan tidak terpengaruh. Memerlukan `write:businesses`.",
        "operationId": "delete_v3_session_kyb_party_draft",
        "x-didit-sdk": {
          "resource": "sessions",
          "method": "delete_kyb_party_draft",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Sessions"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "sessionId",
            "in": "path",
            "required": true,
            "description": "UUID dari sesi Verifikasi Bisnis (KYB). UUID ini harus dimiliki oleh aplikasi yang terkait dengan kunci API.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "33333333-4444-5555-6666-777777777777"
            }
          },
          {
            "name": "draftId",
            "in": "path",
            "required": true,
            "description": "UUID draf pihak (`draft_id` yang dikembalikan saat dibuat).",
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "5b0d7a52-9d3e-4f0c-8c6a-0e5f3a1b2c4d"
            }
          },
          {
            "name": "node_id",
            "in": "query",
            "required": false,
            "description": "Node alur kerja dari langkah KYB. Hanya diperlukan jika alur kerja memiliki lebih dari satu node KYB; secara default Didit menggunakan node milik sesi itu sendiri.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Draf dihapus. Tidak ada isi."
          },
          "401": {
            "description": "Kunci API dengan cakupan terbatas telah kedaluwarsa. Ini satu-satunya kasus yang mengembalikan `401`: kunci yang hilang, tidak valid, atau dicabut mengembalikan `403`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "Pesan kesalahan yang mudah dibaca manusia."
                    }
                  }
                },
                "examples": {
                  "Expired key": {
                    "summary": "Tanggal kedaluwarsa kunci telah lewat",
                    "value": {
                      "detail": "This API key has expired."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Kegagalan autentikasi atau otorisasi. Kunci yang hilang mengembalikan `403`, begitu juga dengan kunci dari aplikasi lain, kunci dengan cakupan tanpa izin yang dibutuhkan endpoint ini, dan permintaan dari luar daftar izin IP kunci tersebut; kunci yang salah, dicabut, atau kedaluwarsa mengembalikan `401`. Bedakan kegagalan tersebut berdasarkan `detail`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "Pesan kesalahan yang mudah dibaca manusia."
                    }
                  }
                },
                "examples": {
                  "Missing or invalid credentials": {
                    "summary": "Tidak ada header x-api-key, atau kunci gagal divalidasi",
                    "value": {
                      "detail": "Authentication credentials were not provided or are invalid."
                    }
                  },
                  "Other application": {
                    "summary": "Kunci valid milik aplikasi yang berbeda dari sesi",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Scoped key without decisions write": {
                    "summary": "Kunci ber-scope tidak memiliki decisions: write",
                    "value": {
                      "detail": "This API key has no write access to decisions."
                    }
                  },
                  "IP not allowed": {
                    "summary": "Permintaan dari luar daftar izin IP kunci",
                    "value": {
                      "detail": "This API key can't be used from this IP address."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Sesi atau draf tidak ada, atau sesi berada di luar aplikasi yang terkait dengan kunci atau batas kunci dengan cakupan terbatas.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "Pesan kesalahan yang mudah dibaca manusia."
                    }
                  }
                },
                "example": {
                  "detail": "Session not found."
                }
              }
            }
          },
          "409": {
            "description": "Sesi telah selesai (`kyb_session_not_writable`).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "Pesan kesalahan yang mudah dibaca manusia."
                    },
                    "code": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "detail": "This verification session is no longer accepting changes.",
                  "code": "kyb_session_not_writable"
                }
              }
            }
          },
          "429": {
            "description": "Batas laju terlampaui: 300 permintaan penulisan (POST, PATCH, DELETE) per menit per kunci API. Tunggu selama `Retry-After` detik sebelum mencoba lagi; header `X-RateLimit-*` menunjukkan anggaran tersebut.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "Pesan kesalahan yang mudah dibaca manusia."
                    }
                  }
                },
                "examples": {
                  "Rate limited": {
                    "summary": "Anggaran untuk menit saat ini habis",
                    "value": {
                      "detail": "Write request rate limit exceeded. You can make up to 300 requests per minute."
                    }
                  }
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Detik untuk menunggu sebelum mencoba lagi.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "example": 30
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nclient.sessions.delete_kyb_party_draft(\n    \"33333333-4444-5555-6666-777777777777\",\n    \"5b0d7a52-9d3e-4f0c-8c6a-0e5f3a1b2c4d\",\n)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nawait didit.sessions.deleteKybPartyDraft(\n  \"33333333-4444-5555-6666-777777777777\",\n  \"5b0d7a52-9d3e-4f0c-8c6a-0e5f3a1b2c4d\",\n);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nif err := client.Sessions.DeleteKYBPartyDraft(ctx, \"33333333-4444-5555-6666-777777777777\", \"5b0d7a52-9d3e-4f0c-8c6a-0e5f3a1b2c4d\", didit.SessionsDeleteKYBPartyDraftParams{}); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nclient.sessions().deleteKybPartyDraft(\"33333333-4444-5555-6666-777777777777\", \"5b0d7a52-9d3e-4f0c-8c6a-0e5f3a1b2c4d\");"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$didit->sessions->deleteKybPartyDraft('33333333-4444-5555-6666-777777777777', '5b0d7a52-9d3e-4f0c-8c6a-0e5f3a1b2c4d');"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.sessions.delete_kyb_party_draft(\n  \"33333333-4444-5555-6666-777777777777\",\n  \"5b0d7a52-9d3e-4f0c-8c6a-0e5f3a1b2c4d\"\n)"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nawait client.Sessions.DeleteKybPartyDraftAsync(\"33333333-4444-5555-6666-777777777777\", \"5b0d7a52-9d3e-4f0c-8c6a-0e5f3a1b2c4d\");"
          }
        ]
      }
    },
    "/v3/session/{sessionId}/kyb/parties/submit/": {
      "post": {
        "summary": "Kirim draf pihak KYB",
        "description": "Deklarasikan draf yang disimpan sebagai pihak kunci perusahaan. Ini adalah langkah Pihak Kunci yang di-hosting di bawah kunci API Anda: Didit memutuskan dari pengaturan peran dan ambang batas kepemilikan alur kerja pihak mana yang harus diverifikasi, membuat satu sesi KYC individu (atau sub-sesi KYB untuk pemilik korporat) untuk masing-masing pihak, mengirimkan email yang diminta alur kerja, dan memajukan sesi. Setiap sesi turunan ditagihkan seperti pada alur yang di-hosting. Draf akan dikonsumsi. Mengulangi panggilan setelah pengiriman yang berhasil tidak mengubah apa pun dan merespons `200` dengan `already_submitted: true` dan pihak yang sudah ada. Sesi harus berada pada langkah Pihak Kunci. Kirimkan `kyc_session_url` setiap orang kepada mereka, atau sematkan. Memerlukan `write:businesses`.",
        "operationId": "post_v3_session_kyb_parties_submit",
        "x-didit-sdk": {
          "resource": "sessions",
          "method": "submit_kyb_parties",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Sessions"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "sessionId",
            "in": "path",
            "required": true,
            "description": "UUID dari sesi Verifikasi Bisnis (KYB). UUID ini harus dimiliki oleh aplikasi yang terkait dengan kunci API.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "33333333-4444-5555-6666-777777777777"
            }
          },
          {
            "name": "node_id",
            "in": "query",
            "required": false,
            "description": "Node alur kerja dari langkah KYB. Hanya diperlukan jika alur kerja memiliki lebih dari satu node KYB; secara default Didit menggunakan node milik sesi itu sendiri.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "locale": {
                    "type": "string",
                    "maxLength": 10,
                    "description": "Lokal yang digunakan untuk menerjemahkan respons langkah yang dituju sesi."
                  }
                }
              },
              "example": {
                "locale": "es"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Pihak yang dideklarasikan (atau sudah dideklarasikan).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "valid": {
                      "type": "boolean"
                    },
                    "next_step": {
                      "type": "string",
                      "nullable": true,
                      "description": "Langkah yang sedang dijalani sesi."
                    },
                    "status": {
                      "type": "string",
                      "description": "Status sesi bisnis."
                    },
                    "advanced": {
                      "type": "boolean",
                      "description": "`true` saat pemanggilan ini mendeklarasikan para pihak dan melanjutkan sesi."
                    },
                    "already_submitted": {
                      "type": "boolean",
                      "description": "`true` saat para pihak telah dinyatakan melalui pemanggilan sebelumnya."
                    },
                    "kyb_key_people_status": {
                      "type": "string"
                    },
                    "parties": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/KYBKeyPeopleParty"
                      }
                    }
                  }
                },
                "example": {
                  "valid": true,
                  "next_step": "FINISHED",
                  "status": "In Progress",
                  "advanced": true,
                  "already_submitted": false,
                  "kyb_key_people_status": "In Progress",
                  "parties": []
                }
              }
            }
          },
          "402": {
            "description": "Organisasi tidak memiliki sisa kredit untuk sesi verifikasi turunan.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "Pesan kesalahan yang mudah dibaca manusia."
                    }
                  }
                },
                "example": {
                  "detail": "Insufficient credits."
                }
              }
            }
          },
          "401": {
            "description": "Kunci API dengan cakupan terbatas telah kedaluwarsa. Ini satu-satunya kasus yang mengembalikan `401`: kunci yang hilang, tidak valid, atau dicabut mengembalikan `403`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "Pesan kesalahan yang mudah dibaca manusia."
                    }
                  }
                },
                "examples": {
                  "Expired key": {
                    "summary": "Tanggal kedaluwarsa kunci telah lewat",
                    "value": {
                      "detail": "This API key has expired."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Kegagalan autentikasi atau otorisasi. Kunci yang hilang mengembalikan `403`, begitu juga dengan kunci dari aplikasi lain, kunci dengan cakupan tanpa izin yang dibutuhkan endpoint ini, dan permintaan dari luar daftar izin IP kunci tersebut; kunci yang salah, dicabut, atau kedaluwarsa mengembalikan `401`. Bedakan kegagalan tersebut berdasarkan `detail`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "Pesan kesalahan yang mudah dibaca manusia."
                    }
                  }
                },
                "examples": {
                  "Missing or invalid credentials": {
                    "summary": "Tidak ada header x-api-key, atau kunci gagal divalidasi",
                    "value": {
                      "detail": "Authentication credentials were not provided or are invalid."
                    }
                  },
                  "Other application": {
                    "summary": "Kunci valid milik aplikasi yang berbeda dari sesi",
                    "value": {
                      "detail": "You do not have permission to perform this action."
                    }
                  },
                  "Scoped key without decisions write": {
                    "summary": "Kunci ber-scope tidak memiliki decisions: write",
                    "value": {
                      "detail": "This API key has no write access to decisions."
                    }
                  },
                  "IP not allowed": {
                    "summary": "Permintaan dari luar daftar izin IP kunci",
                    "value": {
                      "detail": "This API key can't be used from this IP address."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Sesi tidak ada, telah dihapus, milik aplikasi lain, atau berada di luar batas kunci dengan cakupan terbatas; tidak ada detail yang membedakannya.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "Pesan kesalahan yang mudah dibaca manusia."
                    }
                  }
                },
                "example": {
                  "detail": "Session not found."
                }
              }
            }
          },
          "409": {
            "description": "`kyb_no_party_drafts`: tidak ada yang perlu dikirimkan. `kyb_parties_already_submitted`: draf ditambahkan setelah pihak-pihak dideklarasikan. `kyb_step_mismatch`: sesi tidak berada pada langkah Pihak Kunci (`next_step` menyebutkan nama langkahnya). `kyb_session_not_writable`: sesi telah selesai.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "Pesan kesalahan yang mudah dibaca manusia."
                    },
                    "code": {
                      "type": "string"
                    },
                    "next_step": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "detail": "There are no draft parties to submit.",
                  "code": "kyb_no_party_drafts"
                }
              }
            }
          },
          "429": {
            "description": "Batas laju terlampaui: 300 permintaan penulisan (POST, PATCH, DELETE) per menit per kunci API. Tunggu selama `Retry-After` detik sebelum mencoba lagi; header `X-RateLimit-*` menunjukkan anggaran tersebut.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string",
                      "description": "Pesan kesalahan yang mudah dibaca manusia."
                    }
                  }
                },
                "examples": {
                  "Rate limited": {
                    "summary": "Anggaran untuk menit saat ini habis",
                    "value": {
                      "detail": "Write request rate limit exceeded. You can make up to 300 requests per minute."
                    }
                  }
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Detik untuk menunggu sebelum mencoba lagi.",
                "schema": {
                  "type": "integer",
                  "minimum": 1,
                  "example": 30
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.submit_kyb_parties(\n    \"33333333-4444-5555-6666-777777777777\",\n    locale=\"es\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.submitKybParties(\"33333333-4444-5555-6666-777777777777\", {\n  locale: \"es\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.SubmitKYBParties(ctx, \"33333333-4444-5555-6666-777777777777\", didit.SessionsSubmitKYBPartiesParams{\n\tLocale: didit.String(\"es\"),\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.SessionsSubmitKybPartiesParams;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().submitKybParties(\"33333333-4444-5555-6666-777777777777\", SessionsSubmitKybPartiesParams.builder()\n        .locale(\"es\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->sessions->submitKybParties('33333333-4444-5555-6666-777777777777', [\n    'locale' => 'es',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.submit_kyb_parties(\n  \"33333333-4444-5555-6666-777777777777\",\n  locale: \"es\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.SubmitKybPartiesAsync(\"33333333-4444-5555-6666-777777777777\", new SessionsSubmitKybPartiesParams\n{\n    Locale = \"es\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    },
    "/v3/session/{sessionId}/files-export/": {
      "post": {
        "summary": "Ekspor setiap file dari suatu sesi",
        "description": "Mulai menyiapkan satu ZIP berisi setiap gambar, video, dan dokumen dari sesi Verifikasi Pengguna (KYC) atau Verifikasi Bisnis (KYB), dalam kualitas asli: file disimpan di dalam ZIP sesuai hasil pengambilan awal, tidak pernah dikompresi ulang. Menjawab `202` dengan ekspor tersebut; baca dengan `GET /v3/session/{sessionId}/files-export/{exportId}/` hingga `status` menjadi `READY`, lalu unduh `download_url`. Saat ekspor untuk sesi yang sama masih disiapkan, ekspor tersebut dikembalikan alih-alih membuat yang baru.\n\nFile ZIP akan dihapus 24 jam setelah siap, dan seketika saat sesi dihapus. Sesi yang telah dihapus tidak dapat diekspor. Setiap ekspor dan setiap tautan unduhan yang diberikan dicatat ke dalam log audit sesi. Kunci API dengan cakupan membutuhkan `media: read` dan `decisions: read`; pengguna konsol membutuhkan hak istimewa untuk membaca sesi.",
        "operationId": "post_v3_session_files_export",
        "x-didit-sdk": {
          "resource": "sessions",
          "method": "export_files",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Sessions"
        ],
        "parameters": [
          {
            "name": "sessionId",
            "in": "path",
            "required": true,
            "description": "UUID sesi verifikasi (`session_id` yang dikembalikan oleh `POST /v3/session/`). Menerima ID sesi Verifikasi Pengguna (KYC) dan Verifikasi Bisnis (KYB). Sesi yang dihapus mengembalikan `404`.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "11111111-2222-3333-4444-555555555555"
            }
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST 'https://verification.didit.me/v3/session/11111111-2222-3333-4444-555555555555/files-export/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.export_files(\n    \"11111111-2222-3333-4444-555555555555\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.exportFiles(\"11111111-2222-3333-4444-555555555555\");\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.ExportFiles(ctx, \"11111111-2222-3333-4444-555555555555\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().exportFiles(\"11111111-2222-3333-4444-555555555555\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->sessions->exportFiles('11111111-2222-3333-4444-555555555555');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.export_files(\"11111111-2222-3333-4444-555555555555\")\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.ExportFilesAsync(\"11111111-2222-3333-4444-555555555555\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "202": {
            "description": "Ekspor, sedang disiapkan.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SessionFilesExport"
                },
                "example": {
                  "export_id": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee",
                  "session_id": "11111111-2222-3333-4444-555555555555",
                  "status": "PENDING",
                  "file_count": null,
                  "size_bytes": null,
                  "download_url": null,
                  "expires_at": null,
                  "error": null,
                  "created_at": "2026-10-29T12:00:03Z",
                  "completed_at": null
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/session/{sessionId}/files-export/{exportId}/": {
      "get": {
        "summary": "Dapatkan ekspor file sesi",
        "description": "Progres ekspor yang dimulai dengan `POST /v3/session/{sessionId}/files-export/`. Begitu `status` bernilai `READY`, `download_url` adalah URL bertanda tangan dari ZIP yang tetap valid untuk waktu singkat; baca ekspor lagi untuk mendapatkan URL baru hingga `expires_at`. Setiap pembacaan yang memberikan tautan unduhan dicatat ke dalam log audit sesi. Ekspor dari sesi yang telah dihapus mengembalikan `404`.",
        "operationId": "get_v3_session_files_export",
        "x-didit-sdk": {
          "resource": "sessions",
          "method": "get_files_export",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Sessions"
        ],
        "parameters": [
          {
            "name": "sessionId",
            "in": "path",
            "required": true,
            "description": "UUID sesi verifikasi (`session_id` yang dikembalikan oleh `POST /v3/session/`). Menerima ID sesi Verifikasi Pengguna (KYC) dan Verifikasi Bisnis (KYB). Sesi yang dihapus mengembalikan `404`.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "11111111-2222-3333-4444-555555555555"
            }
          },
          {
            "name": "exportId",
            "in": "path",
            "required": true,
            "description": "`export_id` yang dikembalikan oleh `POST /v3/session/{sessionId}/files-export/`.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "example": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee"
            }
          }
        ],
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET 'https://verification.didit.me/v3/session/11111111-2222-3333-4444-555555555555/files-export/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/' \\\n  -H 'x-api-key: YOUR_API_KEY'"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.sessions.get_files_export(\n    \"11111111-2222-3333-4444-555555555555\",\n    \"aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.sessions.getFilesExport(\n  \"11111111-2222-3333-4444-555555555555\",\n  \"aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee\",\n);\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.Sessions.GetFilesExport(ctx, \"11111111-2222-3333-4444-555555555555\", \"aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.sessions().getFilesExport(\"11111111-2222-3333-4444-555555555555\", \"aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee\");\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->sessions->getFilesExport('11111111-2222-3333-4444-555555555555', 'aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee');\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.sessions.get_files_export(\n  \"11111111-2222-3333-4444-555555555555\",\n  \"aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.Sessions.GetFilesExportAsync(\"11111111-2222-3333-4444-555555555555\", \"aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee\");\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ],
        "responses": {
          "200": {
            "description": "Ekspor.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SessionFilesExport"
                },
                "example": {
                  "export_id": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee",
                  "session_id": "11111111-2222-3333-4444-555555555555",
                  "status": "READY",
                  "file_count": 9,
                  "size_bytes": 18734120,
                  "download_url": "https://storage.example.com/session/11111111-2222-3333-4444-555555555555/files-export/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/session-42-files.zip?X-Amz-Signature=...",
                  "expires_at": "2026-10-30T12:00:41Z",
                  "error": null,
                  "created_at": "2026-10-29T12:00:03Z",
                  "completed_at": "2026-10-29T12:00:41Z"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        },
        "security": [
          {
            "ApiKeyAuth": []
          }
        ]
      }
    },
    "/v3/travel-rule/unmatched/": {
      "get": {
        "summary": "Daftar setoran Travel Rule yang belum cocok",
        "description": "Deposit masuk yang masih menunggu data Travel Rule VASP pengirim: transfer mereka adalah `AWAITING_COUNTERPARTY`, `NOT_ENOUGH_COUNTERPARTY_DATA`, atau `COUNTERPARTY_VASP_NOT_FOUND`, tidak ada pesan masuk yang dipasangkan dengannya, dan tidak ada yang mencocokkannya secara manual. Baris dan filternya sama seperti di `GET /v3/travel-rule/transfers/`, terbaru terlebih dahulu, dipaginasi dengan `limit` (default 50) dan `offset`. Pasangkan deposit dengan pesan yang dikirim VASP pengirim menggunakan `POST /v3/travel-rule/unmatched/{transaction_uuid}/match/`.",
        "operationId": "listUnmatchedTravelRuleDeposits",
        "x-didit-sdk": {
          "resource": "travel_rule.unmatched_deposits",
          "method": "list",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Travel Rule"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "direction",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "INBOUND, OUTBOUND, atau keduanya dipisahkan koma. Peka huruf besar/kecil."
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Satu atau lebih status transfer, dipisahkan koma."
          },
          {
            "name": "rail",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Satu atau lebih dari INTERNAL, TRP, GTR, TRUST, VERIFYVASP, SYGNA, EMAIL, TEST_VASP, dipisahkan koma."
          },
          {
            "name": "kind",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "withdrawal, deposit, atau message, dipisahkan koma."
          },
          {
            "name": "currency",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Mata uang transaksi, tidak peka huruf besar/kecil."
          },
          {
            "name": "start_date",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date"
            },
            "description": "Transfer yang dibuat pada atau setelah tanggal ini (UTC), YYYY-MM-DD."
          },
          {
            "name": "end_date",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date"
            },
            "description": "Transfer yang dibuat pada atau sebelum tanggal ini (UTC), YYYY-MM-DD."
          },
          {
            "name": "counterparty",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "`id` entri direktori atau anggota jaringan Didit dari GET /v3/travel-rule/vasps/: transfer Anda dengan pihak lawan tersebut. Nilai yang bukan id yang valid menghasilkan 400."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 1000000
            },
            "description": "Ukuran halaman, nilai default-nya 50."
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 0,
              "maximum": 1000000
            },
            "description": "Baris yang akan dilewati."
          }
        ],
        "responses": {
          "200": {
            "description": "Satu halaman deposit yang tidak cocok.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "count": {
                      "type": "integer"
                    },
                    "next": {
                      "type": "string",
                      "nullable": true
                    },
                    "previous": {
                      "type": "string",
                      "nullable": true
                    },
                    "results": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/TravelRuleTransferRow"
                      }
                    }
                  }
                },
                "example": {
                  "count": 1,
                  "next": null,
                  "previous": null,
                  "results": [
                    {
                      "id": "7d3a1c55-0b9e-4d52-8a3c-1f6e2b9d4a08",
                      "transaction_id": "c41f9b2e-5a8d-4e0c-9f17-3b6d8a2e5c91",
                      "txn_id": "dep-2026-10-20-0007",
                      "txn_date": "2026-10-19T08:41:12Z",
                      "kind": "deposit",
                      "direction": "INBOUND",
                      "status": "AWAITING_COUNTERPARTY",
                      "rail": "TRP",
                      "asset": "ETH",
                      "amount": "1.25",
                      "originator_vasp": "",
                      "beneficiary_vasp": "Example Counterparty VASP",
                      "originator_wallet": "0x77ccff0cc624a53cd8b8d8703ced826710211ec7",
                      "beneficiary_wallet": "0xede2d7e4f5b097e6391ab6bbcf2f47a53f4778cb",
                      "originator_memo": "",
                      "beneficiary_memo": "",
                      "originator_wallet_type": "vasp",
                      "beneficiary_wallet_type": "vasp",
                      "matched_transaction_id": null,
                      "deadline_at": null,
                      "created_at": "2026-10-19T08:41:13Z"
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Nilai filter tidak valid.",
            "content": {
              "application/json": {
                "example": {
                  "start_date": [
                    "Use the YYYY-MM-DD format."
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          }
        },
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nfor item in client.travel_rule.unmatched_deposits.list():\n    print(item)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nfor await (const item of didit.travelRule.unmatchedDeposits.list()) {\n  console.log(item);\n}"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\niter := client.TravelRule.UnmatchedDeposits.ListAutoPaging(ctx, didit.TravelRuleUnmatchedDepositsListParams{})\nfor iter.Next() {\n\tfmt.Printf(\"%+v\\n\", iter.Current())\n}\nif err := iter.Err(); err != nil {\n\tlog.Fatal(err)\n}"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nfor (var item : client.travelRule().unmatchedDeposits().list()) {\n    System.out.println(item);\n}"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\nforeach ($didit->travelRule->unmatchedDeposits->list() as $item) {\n    print_r($item->toArray());\n}"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\ndidit.travel_rule.unmatched_deposits.list.auto_paging_each do |item|\n  puts item.to_h\nend"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nawait foreach (var item in await client.TravelRule.UnmatchedDeposits.ListAsync())\n{\n    Console.WriteLine(JsonSerializer.Serialize(item));\n}"
          }
        ]
      }
    },
    "/v3/travel-rule/unmatched/{transaction_uuid}/match/": {
      "post": {
        "summary": "Cocokkan deposit Travel Rule dengan pesan yang diterima",
        "operationId": "matchUnmatchedTravelRuleDeposit",
        "x-didit-sdk": {
          "resource": "travel_rule.unmatched_deposits",
          "method": "match",
          "auth": "api_key",
          "server": true
        },
        "tags": [
          "Travel Rule"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "description": "Pasangkan deposit masuk yang masih menunggu data pengirim dengan pesan Travel Rule yang dikirimkan oleh VASP pengirim untuk deposit tersebut. Deposit akan mengambil data pengirim, VASP pihak lawan, dan jalur dari pesan tersebut, serta kedua transfer mencatat kecocokan pada lini masa masing-masing. `transaction_uuid` adalah `transaction_id` milik deposit dari `GET /v3/travel-rule/unmatched/`. `transaction_id` di dalam body adalah `transaction_id` pesan yang diterima, dari baris `GET /v3/travel-rule/transfers/?kind=message`; `id` transfer itu sendiri tidak ditemukan. Pesan harus menyangkut aset yang sama dengan deposit. Deposit atau pesan yang dihapus dari Console merespons `404`; yang telah berpindah status (cocok, atau tidak lagi menunggu) merespons `409`.",
        "parameters": [
          {
            "name": "transaction_uuid",
            "in": "path",
            "required": true,
            "description": "`transaction_id` dari deposit yang tidak cocok.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TravelRuleManualMatchRequest"
              },
              "example": {
                "transaction_id": "e90a4d7b-1c2f-4b83-a6d5-8f0e3c1b7a24"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Kedua transfer setelah pencocokan.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TravelRuleManualMatchResponse"
                },
                "example": {
                  "deposit": {
                    "id": "7d3a1c55-0b9e-4d52-8a3c-1f6e2b9d4a08",
                    "transaction_id": "c41f9b2e-5a8d-4e0c-9f17-3b6d8a2e5c91",
                    "txn_id": "dep-2026-10-20-0007",
                    "txn_date": "2026-10-19T08:41:12Z",
                    "kind": "deposit",
                    "direction": "INBOUND",
                    "status": "AWAITING_COUNTERPARTY",
                    "rail": "TRP",
                    "asset": "ETH",
                    "amount": "1.25",
                    "originator_vasp": "Example Counterparty VASP",
                    "beneficiary_vasp": "Example Counterparty VASP",
                    "originator_wallet": "0x77ccff0cc624a53cd8b8d8703ced826710211ec7",
                    "beneficiary_wallet": "0xede2d7e4f5b097e6391ab6bbcf2f47a53f4778cb",
                    "originator_memo": "",
                    "beneficiary_memo": "",
                    "originator_wallet_type": "vasp",
                    "beneficiary_wallet_type": "vasp",
                    "matched_transaction_id": "e90a4d7b-1c2f-4b83-a6d5-8f0e3c1b7a24",
                    "deadline_at": null,
                    "created_at": "2026-10-19T08:41:13Z"
                  },
                  "message": {
                    "id": "2b8e6f10-9c3a-47d1-b5e2-0a4c7d9f3e66",
                    "transaction_id": "e90a4d7b-1c2f-4b83-a6d5-8f0e3c1b7a24",
                    "txn_id": "msg-2026-10-20-0003",
                    "txn_date": "2026-10-19T08:41:12Z",
                    "kind": "message",
                    "direction": "INBOUND",
                    "status": "COMPLETED",
                    "rail": "TRP",
                    "asset": "ETH",
                    "amount": "1.25",
                    "originator_vasp": "Origin CASP SL",
                    "beneficiary_vasp": "Example Counterparty VASP",
                    "originator_wallet": "0x77ccff0cc624a53cd8b8d8703ced826710211ec7",
                    "beneficiary_wallet": "0xede2d7e4f5b097e6391ab6bbcf2f47a53f4778cb",
                    "originator_memo": "",
                    "beneficiary_memo": "",
                    "originator_wallet_type": "vasp",
                    "beneficiary_wallet_type": "vasp",
                    "matched_transaction_id": null,
                    "deadline_at": "2026-10-21T08:41:13Z",
                    "created_at": "2026-10-19T08:41:13Z"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Kesalahan validasi: `transaction_id` tidak ada, merupakan setoran itu sendiri, bukan pesan Travel Rule yang diterima, atau untuk aset yang berbeda dari setoran tersebut; atau transaksi di dalam jalur bukanlah setoran masuk.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Error": {
                    "value": {
                      "transaction_id": [
                        "The travel rule message is for a different asset than the deposit."
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "description": "Deposit atau pesan tidak dikenal, atau salah satunya telah dihapus.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "detail": "No TravelRuleTransfer matches the given query."
                }
              }
            }
          },
          "409": {
            "description": "Deposit tidak lagi menunggu data pengirim, atau pesan sudah cocok dengan deposit.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "detail": {
                      "type": "string"
                    }
                  }
                },
                "examples": {
                  "Error": {
                    "value": {
                      "detail": "This deposit is no longer waiting for originator data."
                    }
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "python",
            "label": "Python",
            "source": "from didit import Didit\n\n# Reads DIDIT_API_KEY.\nclient = Didit()\n\nresult = client.travel_rule.unmatched_deposits.match(\n    \"11111111-2222-3333-4444-555555555555\",\n    transaction_id=\"e90a4d7b-1c2f-4b83-a6d5-8f0e3c1b7a24\",\n)\nprint(result)"
          },
          {
            "lang": "javascript",
            "label": "Node.js",
            "source": "import Didit from \"@didit-protocol/sdk-node\";\n\n// Reads DIDIT_API_KEY.\nconst didit = new Didit();\n\nconst result = await didit.travelRule.unmatchedDeposits.match(\"11111111-2222-3333-4444-555555555555\", {\n  transaction_id: \"e90a4d7b-1c2f-4b83-a6d5-8f0e3c1b7a24\",\n});\nconsole.log(result);"
          },
          {
            "lang": "go",
            "label": "Go",
            "source": "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.TravelRule.UnmatchedDeposits.Match(ctx, \"11111111-2222-3333-4444-555555555555\", didit.TravelRuleManualMatchRequest{\n\tTransactionID: \"e90a4d7b-1c2f-4b83-a6d5-8f0e3c1b7a24\",\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
          },
          {
            "lang": "java",
            "label": "Java",
            "source": "import me.didit.Didit;\nimport me.didit.types.TravelRuleManualMatchRequest;\n\n// Reads DIDIT_API_KEY.\nDidit client = new Didit();\n\nvar result = client.travelRule().unmatchedDeposits().match(\"11111111-2222-3333-4444-555555555555\", TravelRuleManualMatchRequest.builder()\n        .transactionId(\"e90a4d7b-1c2f-4b83-a6d5-8f0e3c1b7a24\")\n        .build());\nSystem.out.println(result);"
          },
          {
            "lang": "php",
            "label": "PHP",
            "source": "<?php\n\nrequire 'vendor/autoload.php';\n\nuse Didit\\DiditClient;\n\n// Reads DIDIT_API_KEY.\n$didit = new DiditClient();\n\n$result = $didit->travelRule->unmatchedDeposits->match('11111111-2222-3333-4444-555555555555', [\n    'transaction_id' => 'e90a4d7b-1c2f-4b83-a6d5-8f0e3c1b7a24',\n]);\nprint_r($result->toArray());"
          },
          {
            "lang": "ruby",
            "label": "Ruby",
            "source": "require \"didit\"\n\n# Reads DIDIT_API_KEY.\ndidit = Didit::Client.new\n\nresult = didit.travel_rule.unmatched_deposits.match(\n  \"11111111-2222-3333-4444-555555555555\",\n  transaction_id: \"e90a4d7b-1c2f-4b83-a6d5-8f0e3c1b7a24\"\n)\nputs result.to_h"
          },
          {
            "lang": "csharp",
            "label": ".NET",
            "source": "using System;\nusing System.Text.Json;\nusing Didit;\n\n// Reads DIDIT_API_KEY.\nusing var client = new DiditClient();\n\nvar result = await client.TravelRule.UnmatchedDeposits.MatchAsync(\"11111111-2222-3333-4444-555555555555\", new TravelRuleManualMatchRequest\n{\n    TransactionId = \"e90a4d7b-1c2f-4b83-a6d5-8f0e3c1b7a24\",\n});\nConsole.WriteLine(JsonSerializer.Serialize(result));"
          }
        ]
      }
    }
  },
  "components": {
    "schemas": {
      "DocumentAIDetectedCode": {
        "type": "object",
        "required": [
          "type",
          "page_number",
          "position",
          "x",
          "y",
          "width",
          "height",
          "page_width",
          "page_height",
          "raw_payload",
          "parsed_payload"
        ],
        "properties": {
          "type": {
            "type": "string",
            "description": "Simbologi yang terdeteksi, misalnya `QR_CODE`, `CODE_128`, `EAN_13`, `DATA_MATRIX`, atau `PDF_417`."
          },
          "page_number": {
            "type": "integer",
            "minimum": 1,
            "description": "Nomor halaman berbasis 1."
          },
          "position": {
            "type": "array",
            "nullable": true,
            "description": "Poligon yang terdeteksi dalam koordinat piksel halaman yang dirender. Bernilai `null` jika tidak ada lokasi andal yang tersedia.",
            "items": {
              "type": "array",
              "minItems": 2,
              "maxItems": 2,
              "items": {
                "type": "integer"
              }
            }
          },
          "x": {
            "type": "integer",
            "nullable": true,
            "description": "Tepi kiri bounding box dalam piksel halaman yang dirender."
          },
          "y": {
            "type": "integer",
            "nullable": true,
            "description": "Tepi atas bounding box dalam piksel halaman yang dirender."
          },
          "width": {
            "type": "integer",
            "nullable": true,
            "description": "Lebar bounding-box dalam piksel halaman yang dirender."
          },
          "height": {
            "type": "integer",
            "nullable": true,
            "description": "Tinggi bounding-box dalam piksel halaman yang dirender."
          },
          "page_width": {
            "type": "integer",
            "description": "Lebar halaman yang dirender dalam piksel."
          },
          "page_height": {
            "type": "integer",
            "description": "Tinggi halaman yang dirender dalam piksel."
          },
          "raw_payload": {
            "type": "string",
            "description": "Payload dekoder mentah sebagai string base64 jika tersedia; jika tidak, berupa string kosong."
          },
          "parsed_payload": {
            "nullable": true,
            "description": "String atau nilai terstruktur yang didekodekan. `null` jika kode ditemukan tetapi tidak dapat didekodekan."
          }
        }
      },
      "SessionImportJob": {
        "type": "object",
        "required": [
          "uuid",
          "status",
          "import_type",
          "source_format",
          "source_filename",
          "total_rows",
          "processed_rows",
          "created_count",
          "updated_count",
          "skipped_count",
          "failed_count"
        ],
        "properties": {
          "uuid": {
            "type": "string",
            "format": "uuid",
            "description": "ID pekerjaan impor. Gunakan nilai ini untuk melakukan polling progres dan mengambil kesalahan pada baris."
          },
          "status": {
            "type": "string",
            "enum": [
              "PENDING",
              "PROCESSING",
              "COMPLETED",
              "FAILED",
              "PAUSED",
              "CANCELLED",
              "READY"
            ]
          },
          "import_type": {
            "type": "string",
            "enum": [
              "user_verification",
              "business_verification",
              "status_rules",
              "transactions"
            ]
          },
          "source_format": {
            "type": "string",
            "enum": [
              "csv",
              "ndjson"
            ]
          },
          "source_filename": {
            "type": "string"
          },
          "total_rows": {
            "type": "integer",
            "format": "int64"
          },
          "processed_rows": {
            "type": "integer",
            "format": "int64"
          },
          "checkpoint_row": {
            "type": "integer",
            "format": "int64"
          },
          "created_count": {
            "type": "integer",
            "format": "int64"
          },
          "updated_count": {
            "type": "integer",
            "format": "int64"
          },
          "skipped_count": {
            "type": "integer",
            "format": "int64"
          },
          "failed_count": {
            "type": "integer",
            "format": "int64"
          },
          "total_media_bytes": {
            "type": "integer",
            "format": "int64"
          },
          "last_error": {
            "type": "string",
            "nullable": true
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          },
          "started_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "completed_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "state": {
            "type": "string",
            "enum": [
              "ready",
              "queued",
              "running",
              "paused",
              "completed",
              "errors",
              "failed",
              "cancelled"
            ],
            "description": "Status tugas seperti yang ditampilkan konsol; `errors` adalah tugas selesai dengan baris yang ditolak."
          },
          "source": {
            "type": "string",
            "enum": [
              "file",
              "api",
              "provider"
            ]
          },
          "provider": {
            "type": "string",
            "description": "Sumber migrasi; kosong untuk impor file atau API."
          },
          "provider_options": {
            "type": "object"
          },
          "credential_hint": {
            "type": "string",
            "description": "Karakter-karakter pertama dari kunci yang disimpan oleh migrasi. Kunci itu sendiri tidak pernah dikembalikan."
          },
          "credentials_expires_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "resumes_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Saat tugas yang dijeda oleh batas laju penyedia dilanjutkan kembali secara otomatis."
          },
          "status_mapping": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            }
          },
          "is_dry_run": {
            "type": "boolean"
          },
          "dry_run_summary": {
            "type": "object",
            "description": "Hasil yang ditemukan oleh dry run: `total`, `by_status`, `already_in_didit`, `same_person`, `not_finished`, `failed`, `unmapped_statuses`."
          },
          "face_templates_enabled": {
            "type": "boolean"
          },
          "lawful_basis_confirmed_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "not_finished_count": {
            "type": "integer",
            "format": "int64"
          },
          "same_person_count": {
            "type": "integer",
            "format": "int64"
          },
          "face_templates_count": {
            "type": "integer",
            "format": "int64"
          },
          "face_duplicates_count": {
            "type": "integer",
            "format": "int64"
          },
          "face_blocklist_hits_count": {
            "type": "integer",
            "format": "int64"
          },
          "created_by_name": {
            "type": "string",
            "nullable": true
          },
          "created_by_email": {
            "type": "string",
            "nullable": true
          }
        }
      },
      "SessionImportError": {
        "type": "object",
        "required": [
          "uuid",
          "row_number",
          "error",
          "raw_row"
        ],
        "properties": {
          "uuid": {
            "type": "string",
            "format": "uuid"
          },
          "row_number": {
            "type": "integer",
            "format": "int64"
          },
          "external_id": {
            "type": "string",
            "nullable": true
          },
          "error": {
            "type": "string"
          },
          "raw_row": {
            "type": "object",
            "additionalProperties": true
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "BrandingCustomizationUpdate": {
        "type": "object",
        "description": "Body pembaruan branding parsial. Berikan hanya kolom yang ingin Anda ubah. Warna heksadesimal menerima `#RRGGBB` atau `#RRGGBBAA`. Domain kustom dan email White Label tidak diterima di sini.",
        "properties": {
          "color_primary": {
            "type": "string",
            "description": "Warna header / teks utama."
          },
          "color_secondary": {
            "type": "string",
            "description": "Warna teks paragraf / sekunder."
          },
          "color_background": {
            "type": "string",
            "description": "Warna latar belakang halaman."
          },
          "color_panel": {
            "type": "string",
            "description": "Warna panel / aksen."
          },
          "color_panel_10": {
            "type": "string",
            "description": "Warna panel pada opasitas 10%."
          },
          "color_on_panel_1": {
            "type": "string",
            "description": "Warna teks bantuan pada panel."
          },
          "color_on_panel_2": {
            "type": "string",
            "description": "Warna pil / lencana pada panel."
          },
          "color_on_background": {
            "type": "string",
            "description": "Warna teks pada latar belakang."
          },
          "color_button_1": {
            "type": "string",
            "description": "Warna tombol utama."
          },
          "color_button_2": {
            "type": "string",
            "description": "Warna tombol sekunder."
          },
          "color_button_text_1": {
            "type": "string",
            "description": "Warna teks tombol utama."
          },
          "color_button_text_2": {
            "type": "string",
            "description": "Warna teks tombol sekunder."
          },
          "color_pill_text": {
            "type": "string",
            "description": "Warna teks untuk badge berbentuk pil, input, dan pemilih."
          },
          "border_radius_panel": {
            "type": "integer",
            "minimum": 0,
            "description": "Radius sudut panel dalam piksel."
          },
          "border_radius_buttons": {
            "type": "integer",
            "minimum": 0,
            "description": "Radius sudut tombol dalam piksel."
          },
          "font_family": {
            "type": "string",
            "description": "Nama keluarga font Google (misalnya `Inter`, `AR One Sans`)."
          },
          "font_weight": {
            "type": "string",
            "description": "Ketebalan font yang tersedia untuk famili yang dipilih (misalnya `regular`, `500`, `700`)."
          },
          "app_public_name": {
            "type": "string",
            "nullable": true,
            "description": "Nama publik yang ditampilkan dalam alur verifikasi."
          },
          "privacy_policy_url": {
            "type": "string",
            "nullable": true,
            "description": "URL kebijakan privasi yang ditampilkan kepada pengguna akhir."
          },
          "skip_welcome_screen": {
            "type": "boolean",
            "description": "Lewati layar selamat datang awal."
          },
          "disable_login_with_didit": {
            "type": "boolean",
            "description": "Lanjutkan sebagai tamu daripada menampilkan layar masuk dengan Didit. Tidak dapat diubah kembali ke `false` saat domain kustom dikonfigurasi (400)."
          },
          "hide_progress_bar": {
            "type": "boolean",
            "description": "Sembunyikan bilah kemajuan selama alur berlangsung."
          },
          "callback_seconds": {
            "type": "integer",
            "minimum": 0,
            "description": "Jeda (detik) sebelum mengalihkan ke URL callback."
          },
          "delete_logo_square": {
            "type": "boolean",
            "description": "Jika `true`, menghapus logo persegi saat ini."
          },
          "delete_logo_rectangular": {
            "type": "boolean",
            "description": "Jika `true`, menghapus logo persegi panjang saat ini."
          },
          "delete_logo_rectangular_dark": {
            "type": "boolean",
            "description": "Jika `true`, menghapus logo mode gelap saat ini, dan `logo_rectangular_dark` kemudian bernilai `null`. Jika permintaan multipart yang sama juga mengunggah `image_rectangular_dark`, unggahan tersebut yang diprioritaskan."
          },
          "delete_favicon": {
            "type": "boolean",
            "description": "Jika `true`, menghapus favicon saat ini."
          }
        }
      },
      "BrandingCustomization": {
        "type": "object",
        "description": "Branding White Label untuk aplikasi: warna, font, radius, URL logo, dan opsi UI/UX. URL logo hanya dapat dibaca (atur dengan mengunggah gambar). Domain kustom dan email White Label tidak disertakan.",
        "properties": {
          "color_primary": {
            "type": "string"
          },
          "color_secondary": {
            "type": "string"
          },
          "color_background": {
            "type": "string"
          },
          "color_panel": {
            "type": "string"
          },
          "color_panel_10": {
            "type": "string"
          },
          "color_on_panel_1": {
            "type": "string"
          },
          "color_on_panel_2": {
            "type": "string"
          },
          "color_on_background": {
            "type": "string"
          },
          "color_button_1": {
            "type": "string"
          },
          "color_button_2": {
            "type": "string"
          },
          "color_button_text_1": {
            "type": "string"
          },
          "color_button_text_2": {
            "type": "string"
          },
          "color_pill_text": {
            "type": "string"
          },
          "border_radius_panel": {
            "type": "integer"
          },
          "border_radius_buttons": {
            "type": "integer"
          },
          "font_family": {
            "type": "string"
          },
          "font_weight": {
            "type": "string"
          },
          "font_url": {
            "type": "string",
            "nullable": true,
            "description": "Hanya baca. URL stylesheet Google Fonts hasil resolusi untuk keluarga font yang dipilih."
          },
          "logo_square": {
            "type": "string",
            "nullable": true,
            "description": "URL logo persegi bersifat hanya-baca. Unggah melalui `image_square`."
          },
          "logo_rectangular": {
            "type": "string",
            "nullable": true,
            "description": "URL logo persegi panjang bersifat hanya-baca. Unggah melalui `image_rectangular`."
          },
          "logo_rectangular_dark": {
            "type": "string",
            "format": "uri",
            "nullable": true,
            "description": "Hanya-baca. URL bertanda tangan sementara dari logo persegi panjang untuk mode gelap, ditampilkan pada latar belakang gelap. Bernilai `null` jika tidak ada logo gelap yang diatur atau logo persegi panjang tidak ditampilkan untuk akun Anda. Unggah dengan `image_rectangular_dark`."
          },
          "favicon": {
            "type": "string",
            "nullable": true,
            "description": "URL favicon bersifat hanya-baca. Unggah melalui `image_favicon`."
          },
          "app_public_name": {
            "type": "string",
            "nullable": true
          },
          "privacy_policy_url": {
            "type": "string",
            "nullable": true
          },
          "skip_welcome_screen": {
            "type": "boolean"
          },
          "disable_login_with_didit": {
            "type": "boolean"
          },
          "hide_progress_bar": {
            "type": "boolean"
          },
          "callback_seconds": {
            "type": "integer"
          }
        }
      },
      "WebhookEvent": {
        "type": "string",
        "description": "Nama event webhook yang didukung. Gunakan string persis ini di `subscribed_events`; nilai yang tidak didukung akan ditolak.",
        "enum": [
          "status.updated",
          "data.updated",
          "user.status.updated",
          "user.data.updated",
          "business.status.updated",
          "business.data.updated",
          "activity.created",
          "transaction.created",
          "transaction.status.updated",
          "travel_rule.status.updated",
          "workflow.compliance_changed",
          "transaction_rule_suggestions.created",
          "auth.signup",
          "auth.login",
          "auth.login_failed",
          "auth.password_reset_requested",
          "auth.password_reset_completed",
          "auth.mfa_changed",
          "auth.new_device",
          "auth.account_locked",
          "investigator.report.ready",
          "investigator.decision.automated",
          "investigator.decision.overridden",
          "investigator.decision.contested",
          "investigator.question.raised",
          "investigator.automation.paused",
          "investigator.rfi.answered",
          "investigator.rfi.overdue",
          "investigator.drift.detected",
          "investigator.sla.breached",
          "investigator.qa.failed",
          "investigator.external.report.ready"
        ]
      },
      "WebhookSubscribedEvents": {
        "type": "array",
        "description": "Filter event untuk tujuan webhook ini. Didit hanya mengirimkan webhook yang tipe event-nya sama persis dengan salah satu nilai ini — tidak ada langganan wildcard. Saat dikirim, daftar ini harus berisi setidaknya satu event yang valid (`[]` eksplisit akan ditolak dengan kode 400); tujuan yang daftarnya kosong (kolom tidak disertakan saat pembuatan) tidak akan menerima apa pun. Saat pembaruan, daftar diganti secara keseluruhan, tidak pernah digabungkan.",
        "minItems": 1,
        "uniqueItems": true,
        "items": {
          "$ref": "#/components/schemas/WebhookEvent"
        },
        "example": [
          "status.updated",
          "data.updated"
        ]
      },
      "PhoneVerificationSendResponse": {
        "type": "object",
        "properties": {
          "request_id": {
            "type": "string",
            "format": "uuid",
            "description": "ID sesi verifikasi. Pengiriman `Retry` mengembalikan `request_id` yang sama dengan pengiriman asli. ID ini muncul di Business Console, dikembalikan lagi oleh `POST /v3/phone/check/` yang telah selesai diproses, dan dapat diteruskan ke `GET /v3/session/{sessionId}/decision/`."
          },
          "status": {
            "type": "string",
            "enum": [
              "Success",
              "Retry",
              "Blocked"
            ],
            "description": "`Success` — OTP dikirim ke verifikasi baru. `Retry` — OTP dikirim ulang untuk verifikasi tertunda yang dibuat oleh pengiriman sebelumnya. `Blocked` — lapisan anti-fraud menolak pengiriman; verifikasi langsung diselesaikan sebagai `Declined` dan tidak ada biaya yang ditagih."
          },
          "reason": {
            "type": "string",
            "nullable": true,
            "description": "Alasan pengiriman berstatus `Blocked` (misalnya, `repeated_attempts`, `suspicious`, `spam`). Bernilai `null` pada `Success` dan `Retry`."
          },
          "vendor_data": {
            "type": "string",
            "nullable": true,
            "description": "Salinan `vendor_data` yang disimpan pada sesi (dari pengiriman pertama)."
          },
          "metadata": {
            "type": "object",
            "nullable": true,
            "description": "Salinan `metadata` yang disimpan pada sesi (dari pengiriman pertama)."
          }
        }
      },
      "PhoneVerificationCheckResponse": {
        "type": "object",
        "properties": {
          "request_id": {
            "type": "string",
            "format": "uuid",
            "description": "Pada `Approved`/`Declined`: ID sesi verifikasi yang cocok — identik dengan `request_id` yang dikembalikan oleh `POST /v3/phone/send/`. Pada `Failed` dan `Expired or Not Found`: UUID acak sekali pakai yang tidak dapat dicari kemudian."
          },
          "status": {
            "type": "string",
            "enum": [
              "Approved",
              "Declined",
              "Failed",
              "Expired or Not Found"
            ],
            "description": "`Approved` — kode benar, tidak ada risiko penolakan. `Declined` — terminal: risiko penolakan cocok atau batas percobaan (3) telah habis. `Failed` — kode salah, percobaan masih tersisa. `Expired or Not Found` — tidak ada verifikasi tertunda untuk nomor ini dalam 5 menit terakhir."
          },
          "message": {
            "type": "string",
            "description": "Penjelasan hasil yang mudah dibaca manusia, termasuk jumlah percobaan yang tersisa setelah kode yang salah."
          },
          "phone": {
            "type": "object",
            "nullable": true,
            "description": "Laporan telepon lengkap. Ada (non-null) hanya pada hasil akhir (`Approved`/`Declined`); bernilai `null` pada `Failed` dan tidak ada pada `Expired or Not Found`.",
            "properties": {
              "status": {
                "type": "string",
                "enum": [
                  "Approved",
                  "Declined",
                  "In Review",
                  "Not Finished",
                  "Expired"
                ],
                "description": "Status akhir dari verifikasi telepon. Cocok dengan `status` tingkat teratas untuk pemeriksaan yang sudah selesai."
              },
              "phone_number_prefix": {
                "type": "string",
                "description": "Kode panggilan negara dengan awalan `+` (misalnya, `+1`).",
                "example": "+1"
              },
              "phone_number": {
                "type": "string",
                "description": "Nomor nasional tanpa kode panggilan negara.",
                "example": "4155552671"
              },
              "full_number": {
                "type": "string",
                "description": "Nomor lengkap dalam format E.164.",
                "example": "+14155552671"
              },
              "country_code": {
                "type": "string",
                "nullable": true,
                "description": "Negara ISO 3166-1 alpha-2 dari nomor tersebut.",
                "example": "US"
              },
              "country_name": {
                "type": "string",
                "description": "Nama lengkap negara yang diturunkan dari `country_code`.",
                "example": "United States"
              },
              "carrier": {
                "type": "object",
                "description": "Jaringan saat ini yang melayani nomor tersebut, dari pencarian operator yang dijalankan pada saat finalisasi.",
                "properties": {
                  "name": {
                    "type": "string",
                    "description": "Nama operator. String kosong jika pencarian tidak dapat mengidentifikasinya."
                  },
                  "type": {
                    "type": "string",
                    "description": "Jenis saluran yang dilaporkan oleh pencarian: `mobile`, `fixed_line`, `voip`, `isp`, `vpn`, `toll_free`, `premium_rate`, `pager`, `payphone`, `satellite`, `service`, `shared_cost`, `short_codes_commercial`, `calling_cards`, `local_rate`, `universal_access`, `voice_mail`, `other`, atau `unknown`."
                  }
                }
              },
              "is_disposable": {
                "type": "boolean",
                "description": "`true` saat nomor tersebut milik layanan nomor sementara/sekali pakai."
              },
              "is_virtual": {
                "type": "boolean",
                "description": "`true` saat jenis saluran bersifat virtual (`voip`, `isp`, atau `vpn`)."
              },
              "verification_method": {
                "type": "string",
                "description": "Saluran yang benar-benar mengirimkan OTP setelah pengiriman dikonfirmasi (misalnya, `whatsapp`, `sms`); sebelum itu, saluran yang diminta."
              },
              "verification_attempts": {
                "type": "integer",
                "description": "Jumlah pengiriman OTP untuk verifikasi ini (1, atau 2 setelah coba lagi)."
              },
              "verified_at": {
                "type": "string",
                "format": "date-time",
                "nullable": true,
                "description": "Waktu ketika kode yang benar dimasukkan. `null` jika verifikasi tidak pernah disetujui."
              },
              "warnings": {
                "type": "array",
                "description": "Peringatan risiko yang dicatat selama verifikasi (duplikat, sekali pakai, VoIP, batas percobaan terlampaui, daftar blokir, dll.). Berupa array kosong jika tidak ada.",
                "items": {
                  "type": "object",
                  "properties": {
                    "feature": {
                      "type": "string",
                      "description": "Fitur yang menghasilkan peringatan. Selalu `PHONE` di sini."
                    },
                    "risk": {
                      "type": "string",
                      "description": "Kode risiko yang dapat dibaca mesin."
                    },
                    "additional_data": {
                      "type": "object",
                      "nullable": true,
                      "description": "Konteks khusus risiko (misalnya, id sesi yang terduplikasi untuk risiko duplikat). `null` saat risiko tidak membawa data tambahan."
                    },
                    "log_type": {
                      "type": "string",
                      "enum": [
                        "error",
                        "warning",
                        "information"
                      ],
                      "description": "Tingkat keparahan. Risiko `error` menyebabkan verifikasi ditolak, `warning` menandainya untuk ditinjau, `information` dicatat tanpa memengaruhi status."
                    },
                    "short_description": {
                      "type": "string",
                      "description": "Ringkasan satu baris yang dapat dibaca manusia tentang risiko."
                    },
                    "long_description": {
                      "type": "string",
                      "description": "Penjelasan risiko yang mudah dibaca manusia."
                    }
                  }
                }
              },
              "lifecycle": {
                "type": "array",
                "description": "Jejak audit kronologis verifikasi. Event `type` adalah salah satu dari `PHONE_VERIFICATION_MESSAGE_SENT`, `PHONE_VERIFICATION_RETRY_MESSAGE_SENT`, `PHONE_VERIFICATION_BLOCKED`, `PHONE_DELIVERY_DELIVERED`, `PHONE_DELIVERY_UNDELIVERABLE`, `VALID_CODE_ENTERED`, `INVALID_CODE_ENTERED`, `PHONE_VERIFICATION_APPROVED`, `PHONE_VERIFICATION_DECLINED`, `PHONE_VERIFICATION_IN_REVIEW`, `PHONE_VERIFICATION_EXPIRED`.",
                "items": {
                  "type": "object",
                  "properties": {
                    "type": {
                      "type": "string",
                      "description": "Tipe event."
                    },
                    "timestamp": {
                      "type": "string",
                      "format": "date-time",
                      "description": "Waktu ketika peristiwa terjadi."
                    },
                    "details": {
                      "type": "object",
                      "nullable": true,
                      "description": "Payload khusus event. Event kirim: `{status, reason, channel, actual_channel}` (`actual_channel` terisi setelah pengiriman dikonfirmasi). Event pengiriman: `{channel, status}`. Event entri kode: `{code_tried, status}`. Event status akhir: `null`, atau `{reason}` jika ditolak atau dalam peninjauan."
                    },
                    "fee": {
                      "type": "number",
                      "description": "Jumlah USD yang ditagihkan untuk event ini. Bernilai bukan nol hanya pada event pengiriman (harga pengiriman); 0 untuk entri kode, konfirmasi pengiriman, dan event status."
                    }
                  }
                }
              },
              "matches": {
                "type": "array",
                "description": "Sesi lain dari aplikasi Anda (KYC, KYB, atau API) tempat nomor telepon yang sama digunakan oleh pengguna berbeda (`vendor_data` berbeda). Hingga 5 entri, kecocokan daftar blokir dari entri daftar sintetis ditampilkan pertama jika ada (kecocokan yang berasal dari sesi mempertahankan urutan kueri). Array kosong jika tidak ada kecocokan.",
                "items": {
                  "type": "object",
                  "properties": {
                    "session_id": {
                      "type": "string",
                      "format": "uuid",
                      "description": "ID sesi dari verifikasi lain yang menggunakan nomor telepon ini."
                    },
                    "session_number": {
                      "type": "integer",
                      "description": "Nomor urut sesi yang mudah dibaca manusia."
                    },
                    "vendor_data": {
                      "type": "string",
                      "nullable": true,
                      "description": "`vendor_data` dari sesi tersebut."
                    },
                    "verification_date": {
                      "type": "string",
                      "description": "Waktu ketika sesi tersebut dibuat (`YYYY-MM-DDTHH:MM:SSZ`)."
                    },
                    "phone_number": {
                      "type": "string",
                      "description": "Nomor telepon yang cocok."
                    },
                    "status": {
                      "type": "string",
                      "description": "Status sesi tersebut (misalnya, `Approved`, `Declined`, `In Progress`)."
                    },
                    "is_blocklisted": {
                      "type": "boolean",
                      "description": "Apakah nomor telepon ada di daftar blokir aplikasi Anda."
                    },
                    "api_service": {
                      "type": "string",
                      "nullable": true,
                      "description": "Untuk sesi bertipe API, API mandiri yang membuatnya (misalnya, `PHONE_VERIFICATION`); `null` untuk sesi verifikasi reguler."
                    },
                    "source": {
                      "type": "string",
                      "description": "Tempat kecocokan ditemukan. Biasanya `session`; kecocokan daftar blokir melalui entri daftar organisasi menambahkan kecocokan sintetis di awal dengan `source: \"list_entry\"` serta `session_id`/`session_number` bernilai null."
                    }
                  }
                }
              },
              "phone_social": {
                "$ref": "#/components/schemas/PhoneSocialFootprint"
              },
              "phone_intelligence": {
                "allOf": [
                  {
                    "$ref": "#/components/schemas/PhoneIntelligence"
                  }
                ],
                "description": "Sinyal intelijen telepon. Hanya ada saat `enable_enrichment` bernilai `true` pada pemeriksaan."
              }
            }
          },
          "vendor_data": {
            "type": "string",
            "nullable": true,
            "description": "`vendor_data` dari sesi verifikasi yang cocok. `null` pada `Expired or Not Found`."
          },
          "metadata": {
            "type": "object",
            "nullable": true,
            "description": "`metadata` dari sesi verifikasi yang cocok. `null` pada `Expired or Not Found`."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "Cap waktu respons pemeriksaan ini."
          }
        }
      },
      "EmailVerificationSendResponse": {
        "type": "object",
        "properties": {
          "request_id": {
            "type": "string",
            "format": "uuid",
            "description": "ID sesi verifikasi. Pengiriman `Retry` mengembalikan `request_id` yang sama dengan pengiriman asli. ID ini muncul di Business Console, dikembalikan lagi oleh `POST /v3/email/check/` yang telah selesai diproses, dan dapat diteruskan ke `GET /v3/session/{sessionId}/decision/`."
          },
          "status": {
            "type": "string",
            "enum": [
              "Success",
              "Retry",
              "Undeliverable"
            ],
            "description": "`Success` — OTP dikirim via email untuk verifikasi baru (ditagih). `Retry` — OTP baru dikirim via email untuk verifikasi tertunda yang dibuat dari pengiriman sebelumnya (gratis). `Undeliverable` — alamat gagal dalam validasi keterkiriman atau pesan tidak dapat dikirim; verifikasi langsung diselesaikan sebagai `Declined` dan tidak ada biaya yang ditagih."
          },
          "reason": {
            "type": "string",
            "nullable": true,
            "enum": [
              "email_can_not_be_delivered",
              null
            ],
            "description": "`email_can_not_be_delivered` ketika `status` bernilai `Undeliverable`; selain itu `null`."
          },
          "vendor_data": {
            "type": "string",
            "nullable": true,
            "description": "Salinan `vendor_data` yang disimpan pada sesi (dari pengiriman pertama)."
          },
          "metadata": {
            "type": "object",
            "nullable": true,
            "description": "Salinan `metadata` yang disimpan pada sesi (dari pengiriman pertama)."
          }
        }
      },
      "EmailVerificationCheckResponse": {
        "type": "object",
        "properties": {
          "request_id": {
            "type": "string",
            "format": "uuid",
            "description": "Pada `Approved`/`Declined`: ID sesi verifikasi yang cocok — identik dengan `request_id` yang dikembalikan oleh `POST /v3/email/send/`. Pada `Failed` dan `Expired or Not Found`: UUID acak sekali pakai yang tidak dapat dicari kemudian."
          },
          "status": {
            "type": "string",
            "enum": [
              "Approved",
              "Declined",
              "Failed",
              "Expired or Not Found"
            ],
            "description": "`Approved` — kode benar, tidak ada risiko penolakan. `Declined` — terminal: risiko penolakan cocok atau batas percobaan (3) telah habis. `Failed` — kode salah, percobaan masih tersisa. `Expired or Not Found` — tidak ada verifikasi tertunda untuk alamat ini dalam 5 menit terakhir."
          },
          "message": {
            "type": "string",
            "description": "Penjelasan hasil yang mudah dibaca manusia, termasuk jumlah percobaan yang tersisa setelah kode yang salah."
          },
          "email": {
            "type": "object",
            "nullable": true,
            "description": "Laporan email lengkap. Ada (tidak bernilai null) hanya pada hasil akhir (`Approved`/`Declined`); bernilai `null` pada status `Failed` dan tidak ada pada `Expired or Not Found`.",
            "properties": {
              "status": {
                "type": "string",
                "enum": [
                  "Approved",
                  "Declined",
                  "In Review",
                  "Not Finished",
                  "Expired"
                ],
                "description": "Status akhir dari verifikasi email. Cocok dengan `status` tingkat teratas untuk pemeriksaan yang sudah selesai."
              },
              "email": {
                "type": "string",
                "format": "email",
                "description": "Alamat email yang terverifikasi.",
                "example": "alice@example.com"
              },
              "is_breached": {
                "type": "boolean",
                "description": "`true` jika alamat muncul dalam kebocoran data yang diketahui (pencarian intelijen kebocoran data dijalankan saat finalisasi)."
              },
              "breaches": {
                "type": "array",
                "description": "Hingga 5 kebocoran data terbaru yang diketahui berisi alamat ini. Larik kosong (atau dihilangkan) jika `is_breached` bernilai `false`.",
                "items": {
                  "type": "object",
                  "properties": {
                    "name": {
                      "type": "string",
                      "description": "Pengidentifikasi pelanggaran."
                    },
                    "domain": {
                      "type": "string",
                      "description": "Domain dari layanan yang mengalami kebocoran data."
                    },
                    "breach_date": {
                      "type": "string",
                      "format": "date",
                      "description": "Tanggal pelanggaran terjadi."
                    },
                    "breach_emails_count": {
                      "type": "integer",
                      "description": "Jumlah total akun yang terekspos dalam pelanggaran data."
                    },
                    "description": {
                      "type": "string",
                      "description": "Deskripsi pelanggaran yang mudah dibaca manusia (dapat berisi markup HTML)."
                    },
                    "logo_path": {
                      "type": "string",
                      "description": "URL logo layanan yang mengalami kebocoran data."
                    },
                    "data_classes": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Kategori data yang terekspos, dalam snake_case (misalnya, `email_addresses`, `passwords`)."
                    },
                    "is_verified": {
                      "type": "boolean",
                      "description": "Apakah pelanggaran telah diverifikasi sebagai sah."
                    }
                  }
                }
              },
              "is_disposable": {
                "type": "boolean",
                "description": "`true` saat domain milik penyedia email sekali pakai/sementara yang dikenal."
              },
              "is_undeliverable": {
                "type": "boolean",
                "description": "`true` jika alamat tidak dapat menerima email (validasi sintaks atau DNS/MX gagal, atau pesan terpental)."
              },
              "verification_attempts": {
                "type": "integer",
                "description": "Jumlah pengiriman OTP untuk verifikasi ini (1, atau 2 setelah coba lagi)."
              },
              "verified_at": {
                "type": "string",
                "format": "date-time",
                "nullable": true,
                "description": "Waktu ketika kode yang benar dimasukkan. `null` jika verifikasi tidak pernah disetujui."
              },
              "warnings": {
                "type": "array",
                "description": "Peringatan risiko yang dicatat selama verifikasi (duplikat, bocor, sekali pakai, tidak dapat dikirim, batas percobaan terlampaui, daftar blokir, dll.). Berupa array kosong jika tidak ada.",
                "items": {
                  "type": "object",
                  "properties": {
                    "feature": {
                      "type": "string",
                      "description": "Fitur yang menghasilkan peringatan. Selalu `EMAIL` di sini."
                    },
                    "risk": {
                      "type": "string",
                      "description": "Kode risiko yang dapat dibaca mesin."
                    },
                    "additional_data": {
                      "type": "object",
                      "nullable": true,
                      "description": "Konteks khusus risiko (misalnya, id sesi yang terduplikasi untuk risiko duplikat). `null` saat risiko tidak membawa data tambahan."
                    },
                    "log_type": {
                      "type": "string",
                      "enum": [
                        "error",
                        "warning",
                        "information"
                      ],
                      "description": "Tingkat keparahan. Risiko `error` menyebabkan verifikasi ditolak, `warning` menandainya untuk ditinjau, `information` dicatat tanpa memengaruhi status."
                    },
                    "short_description": {
                      "type": "string",
                      "description": "Ringkasan satu baris yang dapat dibaca manusia tentang risiko."
                    },
                    "long_description": {
                      "type": "string",
                      "description": "Penjelasan risiko yang mudah dibaca manusia."
                    }
                  }
                }
              },
              "lifecycle": {
                "type": "array",
                "description": "Jejak audit kronologis verifikasi. Event `type` adalah salah satu dari `EMAIL_VERIFICATION_MESSAGE_SENT`, `EMAIL_VERIFICATION_RETRY_MESSAGE_SENT`, `VALID_CODE_ENTERED`, `INVALID_CODE_ENTERED`, `EMAIL_VERIFICATION_APPROVED`, `EMAIL_VERIFICATION_DECLINED`, `EMAIL_VERIFICATION_IN_REVIEW`, `EMAIL_VERIFICATION_EXPIRED`.",
                "items": {
                  "type": "object",
                  "properties": {
                    "type": {
                      "type": "string",
                      "description": "Tipe event."
                    },
                    "timestamp": {
                      "type": "string",
                      "format": "date-time",
                      "description": "Waktu ketika peristiwa terjadi."
                    },
                    "details": {
                      "type": "object",
                      "nullable": true,
                      "description": "Payload khusus event. Event kirim: `{status, reason}`. Event entri kode: `{code_tried, status}`. Event status akhir: `null`, atau `{reason}` jika ditolak atau dalam peninjauan."
                    },
                    "fee": {
                      "type": "number",
                      "description": "Jumlah USD yang ditagihkan untuk event ini. Bernilai bukan nol hanya pada pengiriman pertama yang berhasil; 0 untuk percobaan ulang, entri kode, dan event status."
                    }
                  }
                }
              },
              "matches": {
                "type": "array",
                "description": "Sesi lain dari aplikasi Anda (KYC, KYB, atau API) tempat alamat email yang sama digunakan oleh pengguna yang berbeda (`vendor_data` berbeda). Hingga 5 entri; kecocokan daftar blokir sintetis dari entri daftar ditambahkan di awal jika ada (dan hanya jika tidak ada email turunan sesi yang masuk daftar blokir) — kecocokan turunan sesi mempertahankan urutan created_at. Larik kosong jika tidak ada kecocokan.",
                "items": {
                  "type": "object",
                  "properties": {
                    "session_id": {
                      "type": "string",
                      "format": "uuid",
                      "description": "ID sesi dari verifikasi lain yang menggunakan alamat email ini."
                    },
                    "session_number": {
                      "type": "integer",
                      "description": "Nomor urut sesi yang mudah dibaca manusia."
                    },
                    "vendor_data": {
                      "type": "string",
                      "nullable": true,
                      "description": "`vendor_data` dari sesi tersebut."
                    },
                    "verification_date": {
                      "type": "string",
                      "description": "Waktu ketika sesi tersebut dibuat (`YYYY-MM-DDTHH:MM:SSZ`)."
                    },
                    "email": {
                      "type": "string",
                      "description": "Alamat email yang cocok."
                    },
                    "status": {
                      "type": "string",
                      "description": "Status sesi tersebut (misalnya, `Approved`, `Declined`, `In Progress`)."
                    },
                    "is_blocklisted": {
                      "type": "boolean",
                      "description": "Apakah alamat email ada di daftar blokir aplikasi Anda."
                    },
                    "api_service": {
                      "type": "string",
                      "nullable": true,
                      "description": "Untuk sesi bertipe API, API mandiri yang membuatnya (misalnya, `PHONE_VERIFICATION`); `null` untuk sesi verifikasi reguler."
                    },
                    "source": {
                      "type": "string",
                      "description": "Tempat kecocokan ditemukan. Biasanya `session`; kecocokan daftar blokir melalui entri daftar organisasi menambahkan kecocokan sintetis di awal dengan `source: \"list_entry\"` serta `session_id`/`session_number` bernilai null."
                    }
                  }
                }
              },
              "email_social": {
                "$ref": "#/components/schemas/EmailSocialFootprint"
              },
              "email_intelligence": {
                "allOf": [
                  {
                    "$ref": "#/components/schemas/EmailIntelligence"
                  }
                ],
                "description": "Sinyal intelijen email. Hanya ada jika `enable_enrichment` bernilai `true` pada pemeriksaan."
              }
            }
          },
          "vendor_data": {
            "type": "string",
            "nullable": true,
            "description": "`vendor_data` dari sesi verifikasi yang cocok. `null` pada `Expired or Not Found`."
          },
          "metadata": {
            "type": "object",
            "nullable": true,
            "description": "`metadata` dari sesi verifikasi yang cocok. `null` pada `Expired or Not Found`."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "Cap waktu respons pemeriksaan ini."
          }
        }
      },
      "WorkflowListItem": {
        "type": "object",
        "description": "Satu versi alur kerja dalam tampilan daftar.",
        "properties": {
          "uuid": {
            "type": "string",
            "format": "uuid",
            "description": "UUID per versi. Gunakan sebagai `{settings_uuid}` untuk get/update/delete, dan sebagai `workflow_id` saat membuat sesi."
          },
          "workflow_id": {
            "type": "string",
            "format": "uuid",
            "description": "ID grup stabil yang digunakan bersama oleh setiap versi dari alur kerja yang sama. Sama dengan `uuid` untuk versi 1."
          },
          "workflow_label": {
            "type": "string",
            "description": "Nama tampilan untuk alur kerja."
          },
          "workflow_type": {
            "type": "string",
            "nullable": true,
            "description": "Tipe dasar untuk alur kerja sederhana: `kyc`, `kyb`, `adaptive_age_verification`, `biometric_authentication`, dll. `null` untuk alur kerja berbasis graf tanpa fitur KYB."
          },
          "is_default": {
            "type": "boolean",
            "description": "Apakah ini merupakan alur kerja default untuk sesi baru."
          },
          "is_archived": {
            "type": "boolean"
          },
          "is_white_label_enabled": {
            "type": "boolean",
            "description": "Menentukan apakah kustomisasi White Label berlaku untuk sesi yang dibuat dengan alur kerja ini."
          },
          "total_price": {
            "type": "number",
            "description": "Harga tetap per verifikasi dalam USD (angka JSON, tidak termasuk fitur dengan harga variabel seperti DATABASE_VALIDATION dan PHONE_VERIFICATION)."
          },
          "min_price": {
            "type": "number",
            "description": "Harga tetap termurah di seluruh jalur graf alur kerja, dalam USD."
          },
          "max_price": {
            "type": "number",
            "description": "Harga tetap termahal di seluruh jalur graf alur kerja, dalam USD."
          },
          "features": {
            "type": "string",
            "description": "Fitur yang diaktifkan sebagai string tunggal yang digabungkan dengan `\" + \"`, misalnya `\"OCR + LIVENESS + FACE_MATCH\"`. Pisahkan berdasarkan `\" + \"` untuk mendapatkan daftar."
          },
          "is_simple_workflow": {
            "type": "boolean",
            "description": "True saat alur kerja tidak memiliki graf alur kerja kustom."
          },
          "is_editable": {
            "type": "boolean",
            "description": "True jika versi ini adalah `draft` (draf dapat diedit langsung; versi yang diterbitkan bersifat tidak dapat diubah di Console)."
          },
          "workflow_url": {
            "type": "string",
            "format": "uri",
            "description": "URL verifikasi publik yang dapat dibagikan untuk alur kerja ini (`https://verify.didit.me/u/<token>`)."
          },
          "max_retry_attempts": {
            "type": "integer",
            "description": "Jumlah maksimum percobaan ulang yang diizinkan setelah verifikasi yang ditolak (0-10)."
          },
          "retry_window_days": {
            "type": "integer",
            "nullable": true,
            "description": "Jendela bergulir dalam hitungan hari yang digunakan untuk menghitung percobaan ulang (1-365). `null` = batas sepanjang masa."
          },
          "session_expiration_time": {
            "type": "integer",
            "description": "Detik sebelum sesi yang belum selesai kedaluwarsa (3600-2419200)."
          },
          "version": {
            "type": "integer",
            "description": "Nomor versi dalam grup `workflow_id`, dimulai dari 1."
          },
          "status": {
            "type": "string",
            "enum": [
              "draft",
              "published"
            ],
            "description": "Status versi. Sesi baru menggunakan versi `published` terbaru dari suatu grup."
          },
          "has_draft": {
            "type": "boolean",
            "description": "True saat ada versi dalam grup `workflow_id` ini yang saat ini berstatus draf."
          },
          "created_by": {
            "type": "object",
            "nullable": true,
            "description": "Pihak yang membuat versi ini: `{name, email, type}` dengan `type` berupa `user` (pengguna Konsol, `email` terisi) atau `api_key` (`name` adalah ID klien, `email` bernilai null). `null` jika tidak ada pembuat yang dicatat.",
            "properties": {
              "name": {
                "type": "string"
              },
              "email": {
                "type": "string",
                "nullable": true
              },
              "type": {
                "type": "string",
                "enum": [
                  "user",
                  "api_key"
                ]
              }
            }
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "SimpleWorkflowRequest": {
        "type": "object",
        "description": "Buat alur kerja linier sederhana. API mengonversi daftar fitur ini menjadi graf alur kerja berbasis node secara internal. Daftar kolom yang diizinkan secara KETAT: kunci apa pun yang tidak tercantum di sini (termasuk `workflow_type`) akan ditolak dengan 400.",
        "required": [
          "features"
        ],
        "properties": {
          "workflow_label": {
            "type": "string",
            "maxLength": 50,
            "default": "ID Verification",
            "description": "Nama tampilan untuk alur kerja (maksimal 50 karakter). Secara default bernilai `\"ID Verification\"` jika ditiadakan — selalu atur agar alur kerja tetap dapat dibedakan.",
            "example": "Standard KYC"
          },
          "is_default": {
            "type": "boolean",
            "description": "Atur alur kerja ini sebagai default untuk sesi baru."
          },
          "status": {
            "type": "string",
            "enum": [
              "draft",
              "published"
            ],
            "description": "Kosongkan kolom ini untuk membuat alur kerja yang dipublikasikan dan siap digunakan untuk sesi. Gunakan `draft` hanya jika Anda ingin menyimpan tanpa mempublikasikannya."
          },
          "features": {
            "type": "array",
            "minItems": 1,
            "description": "Fitur verifikasi dalam urutan eksekusi. API menautkan setiap item ke item berikutnya dan menambahkan satu node status akhir secara otomatis.",
            "items": {
              "$ref": "#/components/schemas/SimpleWorkflowFeature"
            }
          },
          "is_white_label_enabled": {
            "type": "boolean",
            "description": "Aktifkan kustomisasi White Label untuk sesi yang dibuat dengan alur kerja ini.",
            "default": false
          },
          "is_desktop_allowed": {
            "type": "boolean",
            "description": "Izinkan alur verifikasi berjalan di browser desktop.",
            "default": false
          },
          "max_retry_attempts": {
            "type": "integer",
            "minimum": 0,
            "maximum": 10,
            "default": 3,
            "description": "Upaya coba lagi maksimum yang diizinkan setelah verifikasi yang ditolak. `0` memblokir pengguna setelah penolakan pertama."
          },
          "retry_window_days": {
            "type": "integer",
            "minimum": 1,
            "maximum": 365,
            "nullable": true,
            "default": 7,
            "description": "Jendela bergulir dalam hitungan hari yang digunakan untuk menghitung percobaan ulang. `null` memberlakukan batas sepanjang masa."
          },
          "face_liveness_max_attempts": {
            "type": "integer",
            "minimum": 1,
            "maximum": 3,
            "default": 3,
            "description": "Pengiriman deteksi liveness maksimum per sesi. Default 3: satu upaya awal ditambah dua percobaan ulang. Nilai ini juga disalin ke dalam node alur kerja deteksi liveness dan estimasi usia yang dibuat kecuali ditimpa oleh konfigurasi tingkat fitur."
          },
          "face_match_max_attempts": {
            "type": "integer",
            "minimum": 1,
            "maximum": 3,
            "default": 3,
            "description": "Pengiriman pencocokan wajah maksimum per sesi. Default 3: satu upaya awal ditambah dua percobaan ulang. Nilai ini juga disalin ke dalam node alur kerja pencocokan wajah yang dibuat kecuali ditimpa oleh konfigurasi tingkat fitur."
          },
          "session_expiration_time": {
            "type": "integer",
            "minimum": 3600,
            "maximum": 2419200,
            "default": 604800,
            "description": "Detik sebelum sesi yang belum selesai kedaluwarsa. Minimum 1 jam (3600), maksimum 4 minggu (2419200)."
          }
        }
      },
      "SimpleWorkflowUpdateRequest": {
        "type": "object",
        "description": "Perbarui metadata alur kerja atau ganti seluruh daftar fitur linear. Daftar putih kolom yang KETAT: kunci apa pun yang tidak tercantum di sini akan ditolak dengan respons 400.",
        "properties": {
          "workflow_label": {
            "type": "string",
            "maxLength": 50,
            "description": "Nama tampilan untuk alur kerja (maksimal 50 karakter)."
          },
          "is_default": {
            "type": "boolean",
            "description": "Atur alur kerja ini sebagai default untuk sesi baru."
          },
          "status": {
            "type": "string",
            "enum": [
              "draft",
              "published"
            ],
            "description": "Mengontrol versi. Jangan sertakan untuk memperbarui versi saat ini di tempat (draf dipublikasikan secara otomatis). `published` pada versi yang sudah dipublikasikan akan membuat dan mengembalikan versi BARU. `draft` hanya valid selama versi tersebut masih berupa draf."
          },
          "features": {
            "type": "array",
            "minItems": 1,
            "description": "Jika diberikan, ini menggantikan urutan dan konfigurasi fitur secara menyeluruh.",
            "items": {
              "$ref": "#/components/schemas/SimpleWorkflowFeature"
            }
          },
          "is_white_label_enabled": {
            "type": "boolean",
            "description": "Aktifkan kustomisasi White Label untuk sesi yang dibuat dengan alur kerja ini."
          },
          "is_desktop_allowed": {
            "type": "boolean",
            "description": "Izinkan alur verifikasi berjalan di browser desktop."
          },
          "max_retry_attempts": {
            "type": "integer",
            "minimum": 0,
            "maximum": 10,
            "description": "Upaya coba lagi maksimum yang diizinkan setelah verifikasi yang ditolak. `0` memblokir pengguna setelah penolakan pertama."
          },
          "retry_window_days": {
            "type": "integer",
            "minimum": 1,
            "maximum": 365,
            "nullable": true,
            "description": "Jendela bergulir dalam hitungan hari yang digunakan untuk menghitung percobaan ulang. `null` memberlakukan batas sepanjang masa."
          },
          "face_liveness_max_attempts": {
            "type": "integer",
            "minimum": 1,
            "maximum": 3,
            "description": "Pengiriman deteksi liveness maksimum per sesi. Nilai ini juga disalin ke dalam node alur kerja deteksi liveness dan estimasi usia yang dibuat kecuali ditimpa oleh konfigurasi tingkat fitur."
          },
          "face_match_max_attempts": {
            "type": "integer",
            "minimum": 1,
            "maximum": 3,
            "description": "Pengiriman pencocokan wajah maksimum per sesi. Nilai ini juga disalin ke dalam node alur kerja pencocokan wajah yang dibuat kecuali ditimpa oleh konfigurasi tingkat fitur."
          },
          "session_expiration_time": {
            "type": "integer",
            "minimum": 3600,
            "maximum": 2419200,
            "description": "Detik sebelum sesi yang belum selesai kedaluwarsa. Minimum 1 jam (3600), maksimum 4 minggu (2419200)."
          }
        }
      },
      "SimpleWorkflowFeature": {
        "type": "object",
        "required": [
          "feature"
        ],
        "properties": {
          "feature": {
            "type": "string",
            "description": "Fitur yang akan dijalankan. Gunakan nilai huruf kapital yang ditampilkan di sini.",
            "enum": [
              "OCR",
              "NFC",
              "LIVENESS",
              "FACE_MATCH",
              "PROOF_OF_ADDRESS",
              "QUESTIONNAIRE",
              "DOCUMENT_AI",
              "PHONE_VERIFICATION",
              "EMAIL_VERIFICATION",
              "DATABASE_VALIDATION",
              "AML",
              "IP_ANALYSIS",
              "AGE_ESTIMATION",
              "KYB_REGISTRY",
              "KYB_DOCUMENTS",
              "KYB_KEY_PEOPLE",
              "SIGNATURE"
            ]
          },
          "config": {
            "type": "object",
            "description": "Pengaturan khusus fitur. Untuk `QUESTIONNAIRE`, sertakan `questionnaire_uuid` dengan `questionnaire_id` yang dikembalikan oleh endpoint pembuatan kuesioner. Untuk `SIGNATURE`, alur kerja yang dipublikasikan memerlukan dokumen untuk ditandatangani: atur `signature_documents_source` ke `session` atau `both` agar setiap sesi dapat menyediakannya sendiri, atau kirim `status: \"draft\"` dan tambahkan dokumen sebelum Anda memublikasikannya. `signature_level: \"aes\"` ditolak dengan `aes_not_available` selama `signature_availability.aes` bernilai `false` pada alur kerja. Untuk `OCR`, `methods` memilih metode Verifikasi Identitas mana yang boleh digunakan setiap negara (pengambilan dokumen, pencarian non-dokumen ke sumber pemerintah atau sumber otoritatif lainnya, dan dompet identitas digital); jika diabaikan, setiap negara hanya menggunakan pengambilan dokumen. Untuk `SIGNATURE`, lihat [Pengaturan Tanda Tangan Elektronik](/id/management-api/workflows/feature-configs#tanda-tangan-elektronik): `signature_level` menerima `simple` (default, tidak memerlukan verifikasi identitas, email, atau telepon) dan `aes` untuk saat ini, serta dokumen alur kerja dan kolomnya dikelola di konsol, jadi melalui API kirimkan dokumen dan kolom per sesi dengan `signature_documents_source: \"session\"`.",
            "additionalProperties": true
          },
          "label": {
            "type": "string",
            "description": "Label internal opsional untuk node alur kerja ini."
          }
        }
      },
      "ReviewItem": {
        "type": "object",
        "description": "Satu entri dalam umpan peninjauan / aktivitas sesi. Perubahan status memuat `previous_status`, `new_status`, `previous_value`, `new_value`, dan `changed_fields`; komentar memuat `comment` dan (untuk komentar Console) `mentioned_emails`; kolom selebihnya bernilai `null` atau kosong jika tidak berlaku untuk jenis aktivitas tersebut.",
        "properties": {
          "uuid": {
            "type": "string",
            "format": "uuid",
            "description": "Pengenal unik entri feed ini.",
            "example": "de0561bc-5583-4409-9171-1a31a4c8a5f4"
          },
          "activity_type": {
            "type": "string",
            "enum": [
              "COMMENT",
              "STATUS_UPDATED",
              "KYC_DATA_UPDATED",
              "POA_DATA_UPDATED",
              "FILE_ADDED",
              "FILE_REMOVED",
              "AML_ONGOING_MATCH",
              "AML_STATUS_UPDATED",
              "AML_HIT_STATUS_UPDATED",
              "KYB_DATA_UPDATED",
              "KYB_DOCUMENT_UPLOADED",
              "TAG_ADDED",
              "TAG_REMOVED",
              "FEATURE_OVERRIDE_PENDING",
              "FEATURE_OVERRIDE_APPLIED",
              "FEATURE_OVERRIDE_CANCELLED"
            ],
            "description": "Jenis aktivitas yang dicatat oleh entri ini. Baris `STATUS_UPDATED` berasal dari keputusan manual (`PATCH /v3/session/{session_id}/update-status/`) dan dari entri yang ditambahkan melalui `POST …/reviews/` (yang secara default berjenis ini meskipun tidak ada status yang dicatat). Baris `COMMENT` berasal dari peninjau Console; tampilan halaman detail Console juga disimpan sebagai baris `COMMENT` yang ditandai dengan `metadata.system_event = \"DETAIL_VIEWED\"`. Jenis lainnya melacak pengeditan data, perubahan file, tag, dan aktivitas pemantauan AML. Baris STATUS_UPDATED juga ditulis oleh aktor sistem (misalnya Pemantauan AML Berkelanjutan dengan actor_type SYSTEM, dan pembaruan status fitur otomatis), bukan hanya oleh endpoint update-status dan entri peninjauan manual. `FEATURE_OVERRIDE_PENDING`, `FEATURE_OVERRIDE_APPLIED`, dan `FEATURE_OVERRIDE_CANCELLED` mencatat override status satu pemeriksaan (`PATCH /v3/session/{session_id}/features/{node_id}/update-status/`): diminta untuk menunggu alur selesai, diterapkan, atau dibatalkan. Entri tersebut membawa status pemeriksaan dalam `previous_value` / `new_value` (`{\"status\": ...}`), membiarkan `previous_status` dan `new_status` bernilai `null`, dan menyebutkan nama override dalam `metadata` (`feature_override_id`, `node_id`, `feature_model`, `forced`, `state`, `cancel_reason`). Entri untuk permintaan membawa `comment` peninjau; override yang diterapkan saat alur selesai dicatat dengan `actor_type` `SYSTEM`.",
            "example": "STATUS_UPDATED"
          },
          "actor_display": {
            "type": "string",
            "description": "Label pembuat yang mudah dibaca manusia, diselesaikan secara berurutan: nama lengkap aktor → pengidentifikasi akun Console → bagian lokal dari `actor_email` → `\"API Client\"` (untuk aktor `API_KEY`) → `\"System\"` (untuk aktor `SYSTEM`) → `\"Unknown\"`. Entri yang dibuat melalui `POST …/reviews/` selalu menampilkan `\"Unknown\"` karena endpoint tersebut tidak mencatat atribusi aktor.",
            "example": "API Client"
          },
          "actor_email": {
            "type": "string",
            "nullable": true,
            "description": "Email pengguna Console yang melakukan tindakan tersebut. `null` untuk aktor kunci API dan sistem.",
            "example": null
          },
          "actor_type": {
            "type": "string",
            "enum": [
              "API_KEY",
              "CONSOLE_USER",
              "SYSTEM"
            ],
            "description": "Pihak yang melakukan tindakan: kunci API, pengguna Konsol, atau Didit sendiri (`SYSTEM`, misalnya Pemantauan AML Berkelanjutan). Entri yang dibuat melalui `POST …/reviews/` membawa nilai default `CONSOLE_USER` terlepas dari pemanggilnya.",
            "example": "API_KEY"
          },
          "new_status": {
            "type": "string",
            "nullable": true,
            "enum": [
              "Not Started",
              "In Progress",
              "Approved",
              "Declined",
              "In Review",
              "Expired",
              "Abandoned",
              "Kyc Expired",
              "Resubmitted",
              "Awaiting User"
            ],
            "description": "Status sesi yang dicatat oleh entri ini (untuk pembaruan status). `null` untuk komentar dan entri perubahan data.",
            "example": "Approved"
          },
          "previous_status": {
            "type": "string",
            "nullable": true,
            "enum": [
              "Not Started",
              "In Progress",
              "Approved",
              "Declined",
              "In Review",
              "Expired",
              "Abandoned",
              "Kyc Expired",
              "Resubmitted",
              "Awaiting User"
            ],
            "description": "Status sesi sebelum perubahan. Diisi pada entri `STATUS_UPDATED` yang ditulis oleh endpoint pembaruan status; `null` pada entri yang ditambahkan melalui `POST …/reviews/`. Juga diisi pada baris STATUS_UPDATED yang ditulis sistem.",
            "example": "In Review"
          },
          "comment": {
            "type": "string",
            "nullable": true,
            "description": "Catatan teks bebas yang dilampirkan pada entri, atau `null`.",
            "example": "Document re-checked manually; address matches."
          },
          "mentioned_emails": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "email"
            },
            "description": "Pengguna Console yang disebut dengan `@email` dalam komentar. Selalu kosong untuk entri yang dibuat melalui API ini — pemrosesan sebutan adalah fitur khusus Console.",
            "example": []
          },
          "previous_value": {
            "type": "object",
            "nullable": true,
            "description": "Cuplikan data yang diubah sebelum tindakan, misalnya `{\"status\": \"In Review\"}` pada perubahan status. `null` jika tidak ada yang diubah.",
            "example": {
              "status": "In Review"
            }
          },
          "new_value": {
            "type": "object",
            "nullable": true,
            "description": "Cuplikan data yang diubah setelah tindakan, misalnya `{\"status\": \"Approved\"}`. Bernilai `null` jika tidak ada yang diubah.",
            "example": {
              "status": "Approved"
            }
          },
          "changed_fields": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Nama kolom yang dimodifikasi oleh aktivitas ini (misalnya `[\"status\"]`). Kosong untuk komentar dan entri yang ditambahkan melalui `POST …/reviews/`.",
            "example": [
              "status"
            ]
          },
          "metadata": {
            "type": "object",
            "nullable": true,
            "description": "Konteks tambahan untuk entri yang dibuat oleh sistem. Tampilan halaman detail Console memuat `{\"system_event\": \"DETAIL_VIEWED\", \"detail_type\": \"verification\"}` sehingga dapat difilter dari logika notifikasi. `COMMENT` yang diedit oleh penulisnya di Console memuat `edited_at`, waktu ISO 8601 dari pengeditan terakhir (`comment` dan `mentioned_emails` kemudian memuat teks yang diedit beserta mention-nya). `null` untuk entri biasa.",
            "example": null
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "Waktu ketika entri ditulis, ISO 8601 UTC.",
            "example": "2026-06-12T00:19:31.918735Z"
          }
        }
      },
      "QuestionnaireListItem": {
        "type": "object",
        "description": "Satu versi kuesioner dalam tampilan daftar.",
        "properties": {
          "uuid": {
            "type": "string",
            "format": "uuid",
            "description": "UUID per versi. Gunakan sebagai `{questionnaire_uuid}` untuk get/update/delete dan sebagai `questionnaire_uuid` dalam konfigurasi fitur QUESTIONNAIRE pada alur kerja."
          },
          "title": {
            "type": "string"
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "languages": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "default_language": {
            "type": "string"
          },
          "is_active": {
            "type": "boolean"
          },
          "is_simple_questionnaire": {
            "type": "boolean",
            "description": "True untuk kuesioner linear yang dibuat melalui API ini; false untuk kuesioner berbasis graf yang dibangun di Console."
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          },
          "question_types": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Tipe elemen huruf besar dari pertanyaan yang dapat dijawab, sesuai urutan pembuatan (misalnya `SHORT_TEXT`, `MULTIPLE_CHOICE`, `FILE_UPLOAD`). Elemen struktural `SECTION_HEADER` dan `SEPARATOR` tidak disertakan. Satu entri per pertanyaan, sehingga nilai dapat berulang."
          },
          "workflow_names": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Nama alur kerja yang menggunakan kuesioner ini. Saat ini selalu `[]` pada endpoint ini (hanya diisi dalam daftar Console)."
          },
          "questionnaire_group_id": {
            "type": "string",
            "format": "uuid",
            "description": "Pengidentifikasi stabil yang mengelompokkan semua versi dari kuesioner yang sama."
          },
          "version": {
            "type": "integer",
            "description": "Nomor versi dalam grup, dimulai dari 1."
          },
          "status": {
            "type": "string",
            "enum": [
              "draft",
              "published"
            ]
          },
          "published_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Kapan versi ini dipublikasikan. `null` untuk draf."
          },
          "is_editable": {
            "type": "boolean",
            "description": "True jika versi ini adalah `draft`."
          }
        }
      },
      "SimpleQuestionnaireRequest": {
        "type": "object",
        "description": "Buat kuesioner linier sederhana. API mengonversi `form_elements` menjadi graf kuesioner internal.",
        "required": [
          "title",
          "languages",
          "form_elements"
        ],
        "properties": {
          "title": {
            "type": "string",
            "description": "Nama internal untuk kuesioner."
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "languages": {
            "type": "array",
            "description": "Bahasa yang disertakan dalam setiap label. Harus menyertakan `en`.",
            "items": {
              "type": "string"
            },
            "example": [
              "en"
            ]
          },
          "default_language": {
            "type": "string",
            "description": "Bahasa default. Harus disertakan dalam `languages`.",
            "example": "en"
          },
          "is_active": {
            "type": "boolean",
            "default": true
          },
          "status": {
            "type": "string",
            "enum": [
              "draft",
              "published"
            ],
            "description": "Kosongkan kolom ini untuk membuat kuesioner yang dipublikasikan dan siap digunakan untuk alur kerja."
          },
          "form_elements": {
            "type": "array",
            "minItems": 1,
            "description": "Pertanyaan dalam urutan tepat seperti yang harus dilihat pengguna. Percabangan dan kolom kondisional tidak didukung.",
            "items": {
              "$ref": "#/components/schemas/SimpleQuestionnaireElement"
            }
          }
        }
      },
      "SimpleQuestionnaireUpdateRequest": {
        "type": "object",
        "description": "Perbarui metadata kuesioner atau ganti seluruh daftar `form_elements` linear.",
        "properties": {
          "title": {
            "type": "string"
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "languages": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "default_language": {
            "type": "string"
          },
          "is_active": {
            "type": "boolean"
          },
          "status": {
            "type": "string",
            "enum": [
              "draft",
              "published"
            ]
          },
          "form_elements": {
            "type": "array",
            "minItems": 1,
            "description": "Jika diberikan, ini menggantikan seluruh daftar pertanyaan linear.",
            "items": {
              "$ref": "#/components/schemas/SimpleQuestionnaireElement"
            }
          }
        }
      },
      "SimpleQuestionnaireElement": {
        "type": "object",
        "required": [
          "element_type",
          "label"
        ],
        "properties": {
          "id": {
            "type": "string",
            "description": "ID pertanyaan stabil opsional. Jika diabaikan, API akan menghasilkan `q1`, `q2`, dll. Gunakan huruf kecil, angka, dan garis bawah demi keterbacaan.",
            "example": "source_of_funds"
          },
          "element_type": {
            "type": "string",
            "description": "Tipe pertanyaan. API menerima nilai huruf kecil ini beserta nilai huruf besar yang setara.",
            "enum": [
              "short_text",
              "long_text",
              "dropdown",
              "single_choice",
              "multiple_choice",
              "number",
              "image",
              "file_upload",
              "time",
              "email",
              "address",
              "phone",
              "country",
              "date_picker",
              "consent",
              "section_header",
              "separator",
              "heading",
              "paragraph"
            ]
          },
          "label": {
            "type": "object",
            "description": "Label pertanyaan berdasarkan kode bahasa, misalnya `{ \"en\": \"Source of funds\" }`.",
            "additionalProperties": {
              "type": "string"
            }
          },
          "description": {
            "type": "object",
            "nullable": true,
            "additionalProperties": {
              "type": "string"
            }
          },
          "placeholder": {
            "type": "object",
            "nullable": true,
            "additionalProperties": {
              "type": "string"
            }
          },
          "is_required": {
            "type": "boolean",
            "default": false
          },
          "options": {
            "type": "array",
            "description": "Gunakan untuk `dropdown`, `single_choice`, dan `multiple_choice`. Jika `value` dihilangkan, API akan membuatnya dari label opsi.",
            "items": {
              "type": "object",
              "required": [
                "label"
              ],
              "properties": {
                "value": {
                  "type": "string"
                },
                "label": {
                  "type": "object",
                  "additionalProperties": {
                    "type": "string"
                  }
                }
              }
            }
          },
          "max_files": {
            "type": "integer",
            "minimum": 1,
            "maximum": 5,
            "description": "Gunakan dengan `file_upload` atau `image`."
          },
          "validation": {
            "type": "object",
            "nullable": true,
            "description": "Validasi format opsional untuk `short_text`, `long_text`, atau `number`. Diberlakukan saat pengguna mengisi kolom (mereka tidak dapat melanjutkan hingga lolos) dan diperiksa ulang oleh API saat pengiriman.",
            "properties": {
              "pattern": {
                "type": "string",
                "description": "Ekspresi reguler (subset ECMA-262) yang harus dicocokkan sepenuhnya oleh nilai tersebut. Untuk `short_text` dan `long_text`. Jangan tambahkan jangkar ^/$; seluruh nilai akan dicocokkan."
              },
              "min_length": {
                "type": "integer",
                "minimum": 0,
                "description": "Jumlah karakter minimum. Untuk `short_text` dan `long_text`."
              },
              "max_length": {
                "type": "integer",
                "minimum": 0,
                "description": "Jumlah karakter maksimum. Untuk `short_text` dan `long_text`."
              },
              "min": {
                "type": "number",
                "description": "Nilai numerik minimum. Untuk `number`."
              },
              "max": {
                "type": "number",
                "description": "Nilai numerik maksimum. Untuk `number`."
              },
              "error_message": {
                "type": "object",
                "description": "Pesan terjemahan yang ditampilkan saat validasi gagal, diberi kunci berdasarkan kode bahasa.",
                "additionalProperties": {
                  "type": "string"
                }
              }
            }
          }
        }
      },
      "QuestionnaireDetail": {
        "type": "object",
        "description": "Detail kuesioner lengkap yang dikembalikan dari endpoint GET, POST (buat), dan PATCH (perbarui).",
        "properties": {
          "questionnaire_id": {
            "type": "string",
            "format": "uuid",
            "description": "Pengenal unik kuesioner. Gunakan id ini saat mereferensikan kuesioner dari alur kerja atau dalam permintaan pembaruan/penghapusan berikutnya."
          },
          "title": {
            "type": "string"
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "languages": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "default_language": {
            "type": "string"
          },
          "is_active": {
            "type": "boolean"
          },
          "is_simple_questionnaire": {
            "type": "boolean"
          },
          "graph": {
            "type": "object",
            "description": "Struktur graf dengan start_node dan peta node."
          },
          "sections": {
            "type": "array",
            "description": "Konten kuesioner yang dikelompokkan ke dalam bagian-bagian (berasal dari graf).",
            "items": {
              "type": "object"
            }
          },
          "questionnaire_group_id": {
            "type": "string",
            "format": "uuid",
            "description": "Pengidentifikasi stabil yang mengelompokkan semua versi dari kuesioner yang sama."
          },
          "version": {
            "type": "integer"
          },
          "status": {
            "type": "string",
            "enum": [
              "draft",
              "published"
            ]
          },
          "published_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "is_editable": {
            "type": "boolean",
            "description": "True saat kuesioner masih dapat diedit langsung di tempat (versi draf)."
          }
        }
      },
      "UserListItem": {
        "type": "object",
        "description": "Pengguna yang terverifikasi.",
        "properties": {
          "didit_internal_id": {
            "type": "string",
            "format": "uuid",
            "description": "UUID internal yang stabil dari Didit untuk pengguna ini."
          },
          "vendor_data": {
            "type": "string",
            "nullable": true,
            "description": "Pengidentifikasi unik Anda untuk pengguna ini (diteruskan saat membuat sesi). Nilai ini dapat berupa null jika tidak ada pengidentifikasi vendor yang diberikan."
          },
          "display_name": {
            "type": "string",
            "nullable": true,
            "description": "Nama tampilan kustom yang Anda tetapkan"
          },
          "full_name": {
            "type": "string",
            "nullable": true,
            "description": "Nama lengkap yang diekstrak dari dokumen yang diverifikasi"
          },
          "date_of_birth": {
            "type": "string",
            "format": "date",
            "nullable": true
          },
          "effective_name": {
            "type": "string",
            "nullable": true,
            "description": "Nama terbaik yang tersedia: display_name jika disetel, selain itu full_name"
          },
          "status": {
            "type": "string",
            "enum": [
              "ACTIVE",
              "FLAGGED",
              "BLOCKED"
            ],
            "description": "Status siklus hidup rekaman pengguna (BUKAN status sesi). `ACTIVE` adalah default, `FLAGGED` menandai pengguna untuk perhatian manual, `BLOCKED` mencegah sesi baru untuk `vendor_data` ini."
          },
          "portrait_image_url": {
            "type": "string",
            "nullable": true,
            "description": "URL presigned untuk foto potret pengguna (kedaluwarsa setelah beberapa jam)"
          },
          "session_count": {
            "type": "integer",
            "description": "Jumlah total sesi verifikasi untuk pengguna ini"
          },
          "approved_count": {
            "type": "integer",
            "description": "Jumlah sesi yang disetujui"
          },
          "declined_count": {
            "type": "integer",
            "description": "Jumlah sesi yang ditolak"
          },
          "in_review_count": {
            "type": "integer",
            "description": "Jumlah sesi dalam peninjauan"
          },
          "issuing_states": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Kode ISO 3166-1 alpha-3 dari negara penerbit yang terlihat pada dokumen ID pengguna yang disetujui ini, misalnya `[\"USA\", \"ESP\"]`. Berupa array kosong jika tidak ada."
          },
          "approved_emails": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Alamat email terverifikasi yang dikumpulkan dari sesi pengguna ini yang disetujui, contoh `[\"john@example.com\"]`."
          },
          "approved_phones": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Nomor telepon terverifikasi yang dikumpulkan dari sesi pengguna ini yang disetujui, contoh `[\"+14155551234\"]`."
          },
          "features": {
            "type": "object",
            "description": "Status per-fitur agregat di semua sesi pengguna ini. Kunci yang memungkinkan: `ID_VERIFICATION`, `NFC`, `LIVENESS`, `FACE_MATCH`, `POA`, `QUESTIONNAIRE`, `EMAIL_VERIFICATION`, `PHONE`, `AML`, `IP_ANALYSIS`, `AGE_ESTIMATION`, `DATABASE_VALIDATION`. Nilai yang memungkinkan: `Approved`, `Declined`, `In Review`, `Not Finished`, `Resub Requested`."
          },
          "features_list": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "feature": {
                  "type": "string"
                },
                "status": {
                  "type": "string"
                }
              }
            },
            "description": "Data yang sama dengan `features`, sebagai array berurutan dari objek `{feature, status}`."
          },
          "last_session_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Cap waktu sesi terbaru"
          },
          "first_session_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Cap waktu sesi pertama"
          },
          "last_activity_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Cap waktu aktivitas terbaru pada pengguna ini (sesi, transaksi, perubahan status, pengeditan data, dll.)."
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "uuid": {
                  "type": "string",
                  "format": "uuid"
                },
                "name": {
                  "type": "string"
                },
                "color": {
                  "type": "string"
                }
              }
            },
            "description": "Tag yang ditetapkan untuk pengguna ini"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "BlocklistItem": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "face",
              "document",
              "phone",
              "email"
            ]
          },
          "session_id": {
            "type": "string",
            "format": "uuid"
          },
          "session_number": {
            "type": "integer"
          },
          "blocklisted_at": {
            "type": "string",
            "format": "date-time"
          },
          "face_image": {
            "type": "string",
            "nullable": true
          },
          "document_type": {
            "type": "string",
            "nullable": true
          },
          "document_number": {
            "type": "string",
            "nullable": true
          },
          "phone_number": {
            "type": "string",
            "nullable": true
          },
          "email": {
            "type": "string",
            "nullable": true
          }
        }
      },
      "UserDetailItem": {
        "type": "object",
        "description": "Detail pengguna lengkap. Memperluas UserListItem dengan metadata, komentar, dan updated_at.",
        "allOf": [
          {
            "$ref": "#/components/schemas/UserListItem"
          },
          {
            "type": "object",
            "properties": {
              "metadata": {
                "type": "object",
                "description": "JSON metadata kustom yang Anda lampirkan ke pengguna ini. Default adalah `{}`."
              },
              "tags": {
                "type": "array",
                "description": "Penetapan tag. CATATAN: pada respons detail, setiap entri berupa objek *tautan* tag (`{uuid, tag: {...}, added_by_email, added_by_name, created_at}`), berbeda dengan format datar `{uuid, name, color}` yang digunakan pada respons daftar.",
                "items": {
                  "type": "object",
                  "properties": {
                    "uuid": {
                      "type": "string",
                      "format": "uuid",
                      "description": "UUID penetapan tag (bukan tag itu sendiri)."
                    },
                    "tag": {
                      "type": "object",
                      "properties": {
                        "uuid": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "name": {
                          "type": "string"
                        },
                        "color": {
                          "type": "string"
                        },
                        "description": {
                          "type": "string",
                          "nullable": true
                        },
                        "source": {
                          "type": "string",
                          "enum": [
                            "didit",
                            "custom"
                          ]
                        },
                        "created_at": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "updated_at": {
                          "type": "string",
                          "format": "date-time"
                        }
                      }
                    },
                    "added_by_email": {
                      "type": "string",
                      "nullable": true
                    },
                    "added_by_name": {
                      "type": "string",
                      "nullable": true
                    },
                    "created_at": {
                      "type": "string",
                      "format": "date-time"
                    }
                  }
                }
              },
              "comments": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "uuid": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "comment_type": {
                      "type": "string",
                      "enum": [
                        "COMMENT",
                        "STATUS_CHANGED",
                        "METADATA_UPDATED",
                        "TAG_ADDED",
                        "TAG_REMOVED",
                        "PROFILE_UPDATED"
                      ]
                    },
                    "comment": {
                      "type": "string",
                      "nullable": true
                    },
                    "actor_email": {
                      "type": "string",
                      "nullable": true
                    },
                    "actor_name": {
                      "type": "string",
                      "nullable": true
                    },
                    "previous_status": {
                      "type": "string",
                      "nullable": true,
                      "enum": [
                        "ACTIVE",
                        "FLAGGED",
                        "BLOCKED",
                        null
                      ]
                    },
                    "new_status": {
                      "type": "string",
                      "nullable": true,
                      "enum": [
                        "ACTIVE",
                        "FLAGGED",
                        "BLOCKED",
                        null
                      ]
                    },
                    "previous_value": {
                      "type": "object",
                      "nullable": true,
                      "description": "Nilai kolom sebelumnya untuk entri PROFILE_UPDATED."
                    },
                    "new_value": {
                      "type": "object",
                      "nullable": true,
                      "description": "Nilai kolom baru untuk entri PROFILE_UPDATED."
                    },
                    "changed_fields": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Nama kolom yang diubah oleh entri PROFILE_UPDATED."
                    },
                    "metadata": {
                      "type": "object",
                      "nullable": true
                    },
                    "mentioned_emails": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "created_at": {
                      "type": "string",
                      "format": "date-time"
                    }
                  }
                },
                "description": "Log aktivitas dan komentar untuk pengguna ini (perubahan status, pengeditan profil, catatan manual)."
              },
              "updated_at": {
                "type": "string",
                "format": "date-time"
              }
            }
          }
        ]
      },
      "BusinessListItem": {
        "type": "object",
        "description": "Bisnis yang terverifikasi.",
        "properties": {
          "didit_internal_id": {
            "type": "string",
            "format": "uuid",
            "description": "UUID internal yang stabil dari Didit untuk bisnis ini."
          },
          "vendor_data": {
            "type": "string",
            "nullable": true,
            "description": "Pengidentifikasi unik Anda untuk bisnis ini (diteruskan saat membuat sesi). Nilai ini dapat berupa null jika tidak ada pengidentifikasi vendor yang diberikan."
          },
          "display_name": {
            "type": "string",
            "nullable": true,
            "description": "Nama tampilan kustom yang Anda tetapkan"
          },
          "legal_name": {
            "type": "string",
            "nullable": true,
            "description": "Nama resmi menurut hukum dari registri atau entri manual"
          },
          "registration_number": {
            "type": "string",
            "nullable": true,
            "description": "Nomor registrasi atau nomor pendirian perusahaan"
          },
          "country_code": {
            "type": "string",
            "nullable": true,
            "description": "Negara pendirian (ISO 3166-1 alpha-2, misalnya `GB`, `US`)."
          },
          "effective_name": {
            "type": "string",
            "nullable": true,
            "description": "Nama terbaik yang tersedia: display_name jika disetel, selain itu legal_name"
          },
          "status": {
            "type": "string",
            "enum": [
              "ACTIVE",
              "FLAGGED",
              "BLOCKED"
            ],
            "description": "Status siklus hidup rekaman bisnis (BUKAN status sesi). `ACTIVE` adalah default, `FLAGGED` menandainya untuk perhatian manual, `BLOCKED` mencegah sesi baru untuk `vendor_data` ini."
          },
          "session_count": {
            "type": "integer",
            "description": "Jumlah total sesi verifikasi untuk bisnis ini"
          },
          "approved_count": {
            "type": "integer",
            "description": "Jumlah sesi yang disetujui"
          },
          "declined_count": {
            "type": "integer",
            "description": "Jumlah sesi yang ditolak"
          },
          "in_review_count": {
            "type": "integer",
            "description": "Jumlah sesi dalam peninjauan"
          },
          "features": {
            "type": "object",
            "description": "Status per-fitur agregat di semua sesi KYB bisnis ini. Saat ini satu-satunya kunci adalah `KYB` (status pemeriksaan perusahaan di registri). Nilai yang memungkinkan: `Approved`, `Declined`, `In Review`, `Not Finished`, `Resub Requested`."
          },
          "features_list": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "feature": {
                  "type": "string"
                },
                "status": {
                  "type": "string"
                }
              }
            },
            "description": "Data yang sama dengan `features`, sebagai array berurutan dari objek `{feature, status}`."
          },
          "last_session_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Cap waktu sesi terbaru"
          },
          "first_session_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Cap waktu sesi pertama"
          },
          "last_activity_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Cap waktu aktivitas terbaru (perubahan status, pembaruan sesi, dll.)"
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "uuid": {
                  "type": "string",
                  "format": "uuid"
                },
                "name": {
                  "type": "string"
                },
                "color": {
                  "type": "string"
                }
              }
            },
            "description": "Tag yang ditetapkan untuk bisnis ini"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "BusinessDetailItem": {
        "type": "object",
        "description": "Detail bisnis lengkap. Memperluas BusinessListItem dengan metadata dan updated_at.",
        "allOf": [
          {
            "$ref": "#/components/schemas/BusinessListItem"
          },
          {
            "type": "object",
            "properties": {
              "metadata": {
                "type": "object",
                "description": "JSON metadata kustom yang Anda lampirkan ke bisnis ini. Default adalah `{}`."
              },
              "updated_at": {
                "type": "string",
                "format": "date-time"
              }
            }
          }
        ]
      },
      "TransactionDetail": {
        "type": "object",
        "description": "Catatan pemantauan lengkap untuk satu transaksi, sebagaimana dikembalikan oleh `GET /v3/transactions/{transaction_id}/` dan `POST /v3/transactions/`.",
        "properties": {
          "uuid": {
            "type": "string",
            "format": "uuid",
            "description": "Pengenal transaksi yang stabil dari Didit. Gunakan sebagai `{transaction_id}` untuk panggilan tindak lanjut."
          },
          "environment": {
            "type": "string",
            "enum": [
              "live",
              "sandbox"
            ],
            "description": "Lingkungan aplikasi yang memiliki transaksi tersebut. Transaksi `sandbox` disimpan tetapi tidak pernah dievaluasi, diskrining, diberitahukan, atau ditagih, sehingga `rule_runs` yang kosong berarti \"tidak dievaluasi\"."
          },
          "transaction_number": {
            "type": "integer",
            "description": "Nomor transaksi berurutan dalam cakupan aplikasi yang ditampilkan di Konsol (misalnya `4123`)."
          },
          "txn_id": {
            "type": "string",
            "description": "`transaction_id` yang Anda berikan saat dibuat (maks 128 karakter). Unik per aplikasi."
          },
          "txn_date": {
            "type": "string",
            "format": "date-time",
            "description": "Kapan transaksi terjadi (dari `transaction_at`; defaultnya adalah waktu pengiriman)."
          },
          "zone_id": {
            "type": "string",
            "nullable": true,
            "description": "Pengenal zona waktu IANA yang diberikan saat dibuat."
          },
          "transaction_type": {
            "type": "string",
            "description": "Kategori tingkat atas sebagaimana disimpan: `finance`, `kyc`, `travelRule`, `userPlatformEvent`, `gamblingBet`, `gamblingLimitChange`, `gamblingBonusChange`, `auditTrailEvent`. Perhatikan bahwa nilai multi-kata dikembalikan dalam camelCase bahkan ketika dikirimkan dalam snake_case."
          },
          "action_type": {
            "type": "string",
            "description": "Subtipe dalam kategori tersebut (misalnya `deposit`, `withdrawal`, `transfer`). Default ke kategori jika tidak disediakan."
          },
          "direction": {
            "type": "string",
            "enum": [
              "INBOUND",
              "OUTBOUND"
            ],
            "description": "Arah relatif terhadap subjek. Disimpan dalam huruf besar terlepas dari format huruf yang dikirim (`in`/`out`/`inbound`/`outbound` diterima sebagai input)."
          },
          "status": {
            "type": "string",
            "enum": [
              "APPROVED",
              "IN_REVIEW",
              "DECLINED",
              "AWAITING_USER"
            ],
            "description": "Keputusan pemantauan saat ini. Transaksi dibuat dengan status `APPROVED`; aturan dapat mengubahnya menjadi `IN_REVIEW`/`DECLINED` secara sinkron."
          },
          "source": {
            "type": "string",
            "enum": [
              "LIVE",
              "IMPORTED"
            ],
            "description": "Bagaimana catatan berasal: `LIVE` untuk transaksi yang dikirimkan melalui API atau SDK, `IMPORTED` untuk transaksi yang dimuat melalui impor konsol."
          },
          "amount": {
            "type": "string",
            "description": "Jumlah transaksi sebagai string desimal dengan nol di akhir yang dihilangkan (misalnya `\"1500\"`, `\"0.5\"`, `\"0.123456789012345678\"`). Hingga 18 tempat desimal."
          },
          "currency": {
            "type": "string",
            "description": "Kode mata uang untuk `amount`. Kode alfabet ISO 4217 apa pun diterima (misalnya `EUR`, `USD`, `NGN`), begitu pula simbol aset kripto (misalnya `BTC`). Sebaiknya gunakan kode yang saat ini beredar. Tidak semua kode yang diterima memiliki nilai tukar: jika tidak ada nilai tukar yang tersedia untuk kode tersebut (misalnya unit akuntansi ISO `XSU`, atau simbol kripto yang harganya tidak ditetapkan oleh Didit), konversi otomatis gagal dan `preferred_currency_amount` dikembalikan sebagai null kecuali permintaan menyertakan `amount_in_default_currency` yang telah dikonversi sebelumnya."
          },
          "currency_type": {
            "type": "string",
            "nullable": true,
            "description": "`fiat` atau `crypto`, sebagaimana dikirimkan dalam `currency_kind`."
          },
          "amount_in_default_currency": {
            "type": "string",
            "nullable": true,
            "description": "Jumlah yang Anda berikan setelah dikonversi sebelumnya, sebagai string desimal dengan angka nol di belakangnya dihapus."
          },
          "default_currency_code": {
            "type": "string",
            "nullable": true
          },
          "preferred_currency_amount": {
            "type": "string",
            "nullable": true,
            "description": "`amount` dikonversi ke mata uang pilihan aplikasi, jika tersedia."
          },
          "preferred_currency_code": {
            "type": "string",
            "nullable": true
          },
          "payment_details": {
            "type": "string",
            "nullable": true,
            "description": "Referensi atau memo pembayaran teks bebas dari pengiriman."
          },
          "payment_txn_id": {
            "type": "string",
            "nullable": true,
            "description": "Referensi sistem pembayaran eksternal (misalnya hash transaksi blockchain) dari `payment_reference_id`."
          },
          "score": {
            "type": "integer",
            "description": "Skor risiko yang diakumulasikan oleh aturan (biasanya 0–100). Lebih tinggi = lebih berisiko."
          },
          "severity": {
            "type": "string",
            "nullable": true,
            "enum": [
              "UNKNOWN",
              "LOW",
              "MEDIUM",
              "HIGH",
              "CRITICAL"
            ],
            "description": "Tingkat keparahan risiko kategoris yang ditetapkan oleh aturan/penyedia (`UNKNOWN`, `LOW`, `MEDIUM`, `HIGH`, `CRITICAL`). Bernilai `null` hingga ada yang menetapkannya."
          },
          "decision_reason_code": {
            "type": "string",
            "nullable": true,
            "description": "Alasan yang dapat dibaca mesin untuk `status` saat ini."
          },
          "decision_reason_label": {
            "type": "string",
            "nullable": true,
            "description": "Label yang mudah dibaca manusia untuk `decision_reason_code`."
          },
          "vendor_data": {
            "type": "string",
            "nullable": true,
            "description": "Salinan praktis dari `vendor_data` pemohon."
          },
          "metadata": {
            "type": "object",
            "description": "Cuplikan dari payload `subject` dan `counterparty` seperti yang dikirimkan pada waktu pembuatan."
          },
          "props": {
            "type": "object",
            "description": "`custom_properties` yang Anda berikan saat pembuatan. Setiap kunci dapat direferensikan dalam kondisi aturan sebagai `custom_values.<key>`."
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "uuid": {
                  "type": "string",
                  "format": "uuid"
                },
                "name": {
                  "type": "string"
                },
                "color": {
                  "type": "string"
                },
                "description": {
                  "type": "string",
                  "nullable": true
                },
                "source": {
                  "type": "string",
                  "enum": [
                    "didit",
                    "custom"
                  ],
                  "description": "Apakah tag tersebut merupakan preset Didit atau tag kustom."
                }
              }
            },
            "description": "Tag yang dilampirkan ke transaksi (secara manual atau berdasarkan aturan)."
          },
          "parties": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "uuid": {
                  "type": "string",
                  "format": "uuid"
                },
                "role": {
                  "type": "string",
                  "enum": [
                    "APPLICANT",
                    "REMITTER",
                    "BENEFICIARY",
                    "COUNTERPARTY"
                  ],
                  "description": "Peran pihak. Endpoint pembuatan menetapkan `APPLICANT` (subjek) dan `COUNTERPARTY`."
                },
                "entity_type": {
                  "type": "string",
                  "enum": [
                    "individual",
                    "company",
                    "external",
                    "unhostedWallet"
                  ]
                },
                "kind": {
                  "type": "string",
                  "enum": [
                    "USER",
                    "BUSINESS",
                    "EXTERNAL"
                  ],
                  "description": "Pihak `USER`/`BUSINESS` menautkan kembali ke entitas milik Didit melalui `vendor_data`. Pihak `EXTERNAL` tidak memiliki entitas Didit di belakangnya."
                },
                "vendor_data": {
                  "type": "string",
                  "nullable": true,
                  "description": "Pengenal pengguna/bisnis internal Anda."
                },
                "full_name": {
                  "type": "string",
                  "nullable": true
                },
                "first_name": {
                  "type": "string",
                  "nullable": true
                },
                "last_name": {
                  "type": "string",
                  "nullable": true
                },
                "country_code": {
                  "type": "string",
                  "nullable": true,
                  "description": "Kode negara dari `address.country` yang dikirimkan (biasanya ISO 3166-1 alpha-3)."
                },
                "dob": {
                  "type": "string",
                  "format": "date",
                  "nullable": true,
                  "description": "Tanggal lahir dari `date_of_birth` yang dikirimkan."
                },
                "address": {
                  "type": "object",
                  "description": "Objek alamat seperti yang dikirimkan. `{}` jika tidak disertakan."
                },
                "institution_info": {
                  "type": "object",
                  "description": "Detail institusi sebagaimana dikirimkan. `{}` jika dihilangkan."
                },
                "device": {
                  "type": "object",
                  "description": "Konteks perangkat yang dinormalisasi, termasuk pengayaan IP sisi server di bawah network_context (geolokasi, tanda VPN/pusat data) saat IP diberikan.",
                  "properties": {
                    "fingerprint": {
                      "type": "string",
                      "description": "Sidik jari perangkat yang unik."
                    },
                    "persistent_device_id": {
                      "type": "string",
                      "description": "Pengidentifikasi perangkat lintas-sesi yang stabil (skema fingerprint v2)."
                    },
                    "user_agent": {
                      "type": "string",
                      "description": "String user agent browser atau aplikasi."
                    },
                    "browser_family": {
                      "type": "string",
                      "description": "Famili browser (misalnya Chrome, Firefox, Safari)."
                    },
                    "browser_version": {
                      "type": "string",
                      "description": "String versi browser."
                    },
                    "platform": {
                      "type": "string",
                      "description": "Pengenal platform (web, ios, android, macos, windows, linux)."
                    },
                    "os_family": {
                      "type": "string",
                      "description": "Keluarga sistem operasi (misalnya iOS, Android, Windows)."
                    },
                    "os_version": {
                      "type": "string",
                      "description": "String versi sistem operasi."
                    },
                    "accept_language": {
                      "type": "string",
                      "description": "Nilai header Accept-Language."
                    },
                    "session_id": {
                      "type": "string",
                      "description": "Pengenal sesi (disimpan dalam metadata)."
                    },
                    "session_age_ms": {
                      "type": "number",
                      "description": "Usia sesi dalam milidetik."
                    },
                    "network_context": {
                      "type": "object",
                      "description": "Konteks jaringan dengan alamat IP dan geolokasi.",
                      "properties": {
                        "ip_address": {
                          "type": "string",
                          "description": "Alamat IP klien."
                        },
                        "ip_country_code": {
                          "type": "string",
                          "description": "Negara dari IP yang ditentukan secara geografis (ISO 3166-1 alpha-3)."
                        },
                        "latitude": {
                          "type": "number",
                          "description": "Garis lintang geografis IP."
                        },
                        "longitude": {
                          "type": "number",
                          "description": "Garis bujur geografis IP."
                        }
                      }
                    }
                  }
                },
                "external_party_snapshot": {
                  "type": "object",
                  "nullable": true,
                  "description": "Salinan beku dari data pihak untuk pihak `EXTERNAL`. Bernilai `null` selama pihak tersebut ditautkan ke pengguna atau bisnis Didit."
                }
              }
            },
            "description": "Pihak transaksi (pemohon, pihak lawan)."
          },
          "payment_methods": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "uuid": {
                  "type": "string",
                  "format": "uuid"
                },
                "payment_method_type": {
                  "type": "string",
                  "enum": [
                    "bank_card",
                    "bank_account",
                    "e_wallet",
                    "crypto_wallet",
                    "unhosted_wallet",
                    "other"
                  ]
                },
                "label": {
                  "type": "string",
                  "nullable": true
                },
                "fingerprint": {
                  "type": "string",
                  "nullable": true,
                  "description": "SHA-256 atas `type:account_id:issuing_country` — pengidentifikasi stabil untuk menghubungkan penggunaan kembali instrumen yang sama."
                },
                "account_id": {
                  "type": "string",
                  "nullable": true,
                  "description": "Pengidentifikasi akun (IBAN, alamat dompet, token kartu, …)."
                },
                "issuing_country": {
                  "type": "string",
                  "nullable": true
                },
                "owner_kind": {
                  "type": "string",
                  "enum": [
                    "USER",
                    "BUSINESS",
                    "EXTERNAL"
                  ]
                },
                "vendor_data": {
                  "type": "string",
                  "nullable": true,
                  "description": "Pengidentifikasi Anda untuk pengguna/bisnis pemilik."
                },
                "owner_name": {
                  "type": "string",
                  "nullable": true
                },
                "institution_info": {
                  "type": "object"
                },
                "details": {
                  "type": "object",
                  "description": "Objek `payment_method` mentah sebagaimana dikirimkan."
                },
                "external_owner_snapshot": {
                  "type": "object",
                  "nullable": true
                },
                "role": {
                  "type": "string",
                  "enum": [
                    "SOURCE",
                    "DESTINATION",
                    "FUNDING",
                    "BENEFICIARY"
                  ],
                  "description": "Bagaimana metode ini digunakan dalam transaksi. Endpoint pembuatan menetapkan `SOURCE`/`DESTINATION` dari arah (keluar: subjek = SOURCE; masuk: subjek = DESTINATION)."
                }
              }
            },
            "description": "Metode pembayaran yang ditautkan ke transaksi."
          },
          "documents": {
            "type": "array",
            "description": "File yang dilampirkan ke transaksi dari konsol. `[]` jika tidak ada.",
            "items": {
              "type": "object",
              "properties": {
                "uuid": {
                  "type": "string",
                  "format": "uuid"
                },
                "label": {
                  "type": "string",
                  "nullable": true
                },
                "note": {
                  "type": "string",
                  "nullable": true
                },
                "uploaded_by": {
                  "type": "string",
                  "nullable": true
                },
                "created_at": {
                  "type": "string",
                  "format": "date-time"
                },
                "files": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "uuid": {
                        "type": "string",
                        "format": "uuid"
                      },
                      "file_url": {
                        "type": "string",
                        "format": "uri",
                        "nullable": true,
                        "description": "URL unduhan bertanda tangan berdurasi singkat; ambil saat dibutuhkan alih-alih menyimpannya."
                      },
                      "original_filename": {
                        "type": "string",
                        "nullable": true
                      },
                      "file_size": {
                        "type": "integer",
                        "nullable": true
                      }
                    }
                  }
                }
              }
            }
          },
          "activities": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "uuid": {
                  "type": "string",
                  "format": "uuid"
                },
                "activity_type": {
                  "type": "string",
                  "description": "Contoh: `TRANSACTION_CREATED`, `TRANSACTION_NOTE_ADDED`, `TRANSACTION_STATUS_CHANGED`."
                },
                "source": {
                  "type": "string"
                },
                "status": {
                  "type": "string",
                  "nullable": true
                },
                "title": {
                  "type": "string",
                  "nullable": true
                },
                "description": {
                  "type": "string",
                  "nullable": true
                },
                "metadata": {
                  "type": "object"
                },
                "occurred_at": {
                  "type": "string",
                  "format": "date-time"
                }
              }
            },
            "description": "Entri log aktivitas (pembuatan, catatan, peninjauan manual, perubahan status)."
          },
          "alerts": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "uuid": {
                  "type": "string",
                  "format": "uuid"
                },
                "title": {
                  "type": "string"
                },
                "description": {
                  "type": "string",
                  "nullable": true
                },
                "severity": {
                  "type": "string",
                  "enum": [
                    "UNKNOWN",
                    "LOW",
                    "MEDIUM",
                    "HIGH",
                    "CRITICAL"
                  ]
                },
                "status": {
                  "type": "string",
                  "enum": [
                    "OPEN",
                    "INVESTIGATING",
                    "AWAITING_USER",
                    "PENDING_SAR",
                    "SAR_FILED",
                    "RESOLVED",
                    "DISMISSED"
                  ]
                },
                "source": {
                  "type": "string",
                  "enum": [
                    "RULE",
                    "PROVIDER",
                    "MANUAL"
                  ]
                },
                "metadata": {
                  "type": "object"
                },
                "created_at": {
                  "type": "string",
                  "format": "date-time"
                },
                "due_at": {
                  "type": "string",
                  "format": "date-time",
                  "nullable": true
                }
              }
            },
            "description": "Selalu kosong saat ini. Alert terbuka adalah transaksi dengan status `IN_REVIEW` atau `AWAITING_USER`."
          },
          "rule_runs": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "uuid": {
                  "type": "string",
                  "format": "uuid"
                },
                "rule": {
                  "type": "string",
                  "format": "uuid",
                  "description": "UUID aturan yang dijalankan."
                },
                "rule_title": {
                  "type": "string"
                },
                "rule_description": {
                  "type": "string",
                  "nullable": true
                },
                "rule_category": {
                  "type": "string"
                },
                "matched": {
                  "type": "boolean",
                  "description": "Apakah kondisi aturan cocok dengan transaksi ini. Eksekusi hanya dicatat untuk aturan yang cocok, sehingga evaluasi live selalu bernilai `true`."
                },
                "is_test": {
                  "type": "boolean",
                  "description": "True saat aturan berjalan dalam mode TEST (tidak berpengaruh pada status/skor)."
                },
                "mode": {
                  "type": "string",
                  "enum": [
                    "ACTIVE",
                    "DISABLED",
                    "TEST"
                  ]
                },
                "severity": {
                  "type": "string",
                  "nullable": true
                },
                "score_delta": {
                  "type": "integer",
                  "description": "Skor yang ditambahkan oleh tindakan `add_score` aturan ini."
                },
                "status_target": {
                  "type": "string",
                  "nullable": true,
                  "description": "Status yang ditetapkan oleh tindakan `change_status`, jika ada."
                },
                "action_summary": {
                  "type": "string",
                  "nullable": true,
                  "description": "Ringkasan tindakan yang dijalankan aturan, digabungkan dengan `; ` (misalnya `score +30; change_status:IN_REVIEW; add_tag:high_risk_country`). Bagian-bagian: `score +N`, `change_status:<STATUS>`, `add_tag:<name>`, `add_note`, `add_to_list`, `open_case`. `null` jika aturan tidak menjalankan tindakan apa pun."
                },
                "metadata": {
                  "type": "object",
                  "description": "Detail evaluasi: `scope_match`, `conditions[]`, dan `aggregations[]`. Setiap entri kondisi memuat `field`, `operator`, `expected_value`, `current_value` yang dibaca dari transaksi, `matched`, `group_index`, dan `group_logic`. Setiap entri agregasi (velocity / count / sum) memuat `metric`, `field`, `operator`, `expected_value`, `computed_value` dari hasil evaluasi agregat, `window`, `filters`, `matched`, dan `sample_references`; agregasi asinkron yang ditangguhkan memiliki `computed_value: null` dan `deferred: true`. Grup kondisi bertingkat adalah satu entri `conditions[]` dengan `operator` `any_of` atau `all_of`, `field` bernilai null, dan hasil anggotanya berada di bawah `conditions` miliknya sendiri."
                },
                "created_at": {
                  "type": "string",
                  "format": "date-time"
                }
              }
            },
            "description": "Hasil eksekusi per aturan — aturan mana yang terpicu, beserta dampaknya terhadap skor."
          },
          "provider_results": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "uuid": {
                  "type": "string",
                  "format": "uuid"
                },
                "provider": {
                  "type": "string"
                },
                "result_type": {
                  "type": "string",
                  "enum": [
                    "FIAT_MONITORING",
                    "WALLET_SCREENING",
                    "TRANSACTION_SCREENING",
                    "TRAVEL_RULE",
                    "NETWORK_GRAPH",
                    "CUSTOM"
                  ]
                },
                "status": {
                  "type": "string"
                },
                "severity": {
                  "type": "string",
                  "nullable": true
                },
                "score": {
                  "type": "integer"
                },
                "summary": {
                  "type": "string",
                  "nullable": true
                },
                "payload": {
                  "type": "object",
                  "description": "Payload respons penyedia mentah."
                },
                "created_at": {
                  "type": "string",
                  "format": "date-time"
                }
              }
            },
            "description": "Payload penyedia mentah (skrining AML, analitik blockchain, dll.)."
          },
          "travel_rule": {
            "nullable": true,
            "allOf": [
              {
                "$ref": "#/components/schemas/TransactionTravelRule"
              }
            ],
            "description": "Transfer atau pemeriksaan Travel Rule. Diisi saat `travel_rule_details` dikirimkan, dan juga saat Travel Rule diaktifkan dan transaksi dibuat dengan `transaction_category: travelRule` (Didit menginisiasi pertukaran itu sendiri, bahkan tanpa `travel_rule_details`). `null` saat tidak ada transfer atau pemeriksaan. Pada transfer masuk, `originator_data` dan `beneficiary_data` pihak lawan tetap disamarkan (`data_masked: true`) hingga kepemilikan dompet dikonfirmasi."
          },
          "network_snapshot": {
            "type": "object",
            "nullable": true,
            "description": "Snapshot graf dari transaksi/pihak terkait yang digunakan oleh mesin aturan. Berupa `network_snapshot` yang dikirimkan bersama transaksi atau graf yang dibangun Didit dari skrining dompet AML yang berhasil (yang menggantikan graf yang dikirimkan). `null` jika keduanya tidak ada.",
            "properties": {
              "uuid": {
                "type": "string",
                "format": "uuid"
              },
              "nodes": {
                "type": "array",
                "items": {
                  "type": "object"
                }
              },
              "edges": {
                "type": "array",
                "items": {
                  "type": "object"
                }
              },
              "metrics": {
                "type": "object"
              }
            }
          },
          "remediation": {
            "type": "object",
            "nullable": true,
            "description": "Sesi remediasi yang ditawarkan kepada pengguna ketika verifikasi ulang diperlukan. Digantikan oleh `action_required`, yang merupakan blok kanonikal; dipertahankan untuk kompatibilitas mundur.",
            "properties": {
              "session_id": {
                "type": "string"
              },
              "session_token": {
                "type": "string"
              },
              "url": {
                "type": "string",
                "format": "uri"
              },
              "status": {
                "type": "string"
              }
            }
          },
          "action_required": {
            "type": "object",
            "nullable": true,
            "description": "Tindakan pengguna akhir yang tertunda yang diperlukan untuk menyelesaikan transaksi ini, atau null jika tidak ada. SDK Didit meluncurkan tindakan secara otomatis secara default dan menyegarkan transaksi saat selesai. Dua varian, dibedakan berdasarkan `type`: `verification_session` (sesi verifikasi yang di-hosting yang dibuat oleh tindakan aturan) dan `wallet_ownership` (sesi widget kepemilikan dompet yang dibuat secara otomatis untuk transfer Travel Rule yang memerlukan bukti kendali dompet, diatur oleh pengaturan Travel Rule `auto_wallet_verification`). Ketika keduanya berlaku, `wallet_ownership` diprioritaskan karena memblokir pertukaran Travel Rule.",
            "oneOf": [
              {
                "$ref": "#/components/schemas/TransactionVerificationSessionAction"
              },
              {
                "$ref": "#/components/schemas/TransactionWalletOwnershipAction"
              }
            ],
            "discriminator": {
              "propertyName": "type",
              "mapping": {
                "verification_session": "#/components/schemas/TransactionVerificationSessionAction",
                "wallet_ownership": "#/components/schemas/TransactionWalletOwnershipAction"
              }
            }
          },
          "cost_breakdown": {
            "type": "object",
            "nullable": true,
            "description": "Biaya transaksi ini: `total_price` dan `items`, satu untuk setiap biaya, masing-masing dengan `usage_type`, `price`, `details`, dan `created_at`. Skrining ulang transaksi yang sama merupakan item baru."
          }
        }
      },
      "TravelRuleSettingsDetail": {
        "type": "object",
        "properties": {
          "is_enabled": {
            "type": "boolean",
            "description": "Apakah alur negosiasi Travel Rule terkelola aktif untuk transaksi `travelRule` keluar pada aplikasi ini."
          },
          "jurisdiction": {
            "type": "string",
            "maxLength": 8,
            "description": "Kode yurisdiksi operasional VASP Anda. Default `\"EU\"`. Didit memetakannya ke rezim yang dicantumkan pada transaksi Travel Rule Anda sebagai `travel_rule_regime` (misalnya `EU` atau kode anggota UE menjadi `eu`), yang dapat dijadikan acuan oleh aturan transaksi. Pelanggan Didit lainnya melihatnya sebagai yurisdiksi Anda di direktori VASP setelah jaringan Didit menampilkan profil Anda."
          },
          "name_matching_strictness": {
            "type": "string",
            "enum": [
              "NONE",
              "STRICT",
              "CONTAINS",
              "DEFAULT",
              "FUZZY"
            ],
            "description": "Seberapa ketat nama penerima harus cocok sebelum transfer dapat mencapai COMPLETED. `CONTAINS` menerima nama yang semua katanya muncul di nama lainnya."
          },
          "confirmation_timeout_hours": {
            "type": "integer",
            "minimum": 1,
            "description": "Jumlah jam transfer AWAITING_COUNTERPARTY dapat tetap belum dikonfirmasi sebelum sweeper berkala membuatnya kedaluwarsa. Default 48."
          },
          "timeout_outcome": {
            "type": "string",
            "enum": [
              "HOLD",
              "REJECT",
              "PROCEED"
            ],
            "description": "Hal yang terjadi pada transaksi dasar saat transfer kedaluwarsa. Bawaan: HOLD. sunrise_policy dan non_responsive_policy diutamakan jika berlaku dan telah diatur."
          },
          "threshold_amount": {
            "type": "string",
            "description": "String desimal, dalam mata uang default aplikasi Anda. Jumlah transfer minimum yang memicu pertukaran terkelola; transfer di bawah jumlah tersebut langsung diselesaikan menjadi NOT_APPLICABLE. Didit membandingkan jumlah transaksi yang dikonversi ke mata uang default Anda, atau `amount_in_default_currency` yang Anda kirim; jika tidak ada jumlah terkonversi yang tersedia, ambang batas tidak berlaku. Default-nya adalah \"0.00\" (EU TFR tidak menerapkan jumlah minimum)."
          },
          "ownership_validation_mode": {
            "type": "string",
            "enum": [
              "FULL",
              "SIMPLIFIED",
              "AUTOMATED"
            ],
            "description": "Seberapa banyak bukti yang diperlukan untuk kepemilikan dompet. `FULL` selalu memerlukan bukti (pesan bertanda tangan, deposit uji coba, atau tangkapan layar yang ditinjau), tidak pernah hanya dari pernyataan pengguna akhir. `SIMPLIFIED` menerima deklarasi mandiri di bawah `simplified_validation_threshold` dan bukti di atasnya. `AUTOMATED` memungkinkan buku alamat dan bukti sebelumnya menjawab sendiri, termasuk deklarasi mandiri selama `allow_self_declaration` bernilai true. Default `AUTOMATED`."
          },
          "simplified_validation_threshold": {
            "type": "string",
            "description": "String desimal, default \"0.00\". Dalam mode `SIMPLIFIED`, transfer di bawah jumlah ini (dalam mata uang ambang batas) menerima deklarasi mandiri. Transfer tanpa jumlah dalam mata uang tersebut dihitung sebagai di atasnya."
          },
          "data_sharing_fields": {
            "$ref": "#/components/schemas/TravelRuleDataSharingFields"
          },
          "matching_rules": {
            "$ref": "#/components/schemas/TravelRuleMatchingRules"
          },
          "legal_name": {
            "type": "string",
            "description": "Nama resmi VASP Anda. Wajib diisi (tidak boleh kosong) untuk menetapkan is_enabled ke true."
          },
          "lei": {
            "type": "string",
            "description": "Legal Entity Identifier Anda, ditampilkan di direktori VASP."
          },
          "compliance_email": {
            "type": "string",
            "format": "email",
            "description": "Email kontak kepatuhan untuk profil VASP Anda. Jaringan Didit mencantumkan profil Anda hanya setelah alamat ini dikonfirmasi melalui tautan yang dikirimkan melalui email (POST /v3/travel-rule/settings/compliance-email/confirmation/); mengubahnya memerlukan konfirmasi baru."
          },
          "is_discoverable": {
            "type": "boolean",
            "description": "Menentukan apakah profil VASP Anda dapat dicantumkan dalam jaringan Didit: ditemukan di GET /v3/travel-rule/vasps/ oleh pelanggan Didit lainnya dan dijangkau di rail INTERNAL. Pencantuman juga memerlukan aplikasi produksi, Travel Rule aktif, nama resmi, dan email kepatuhan yang dikonfirmasi; didit_network menyatakan mana yang belum lengkap. Nilai defaultnya adalah true."
          },
          "inbound_auto_accept": {
            "type": "boolean",
            "description": "Jika true, inquiry TRP masuk yang dompet penerimanya merupakan entri buku alamat terverifikasi dengan nama yang cocok akan disetujui secara otomatis. Jika false, inquiry tersebut menunggu dalam status ON_HOLD agar Anda menyetujui atau menolaknya dengan endpoint kepemilikan. Transfer rail INTERNAL dan transfer setelah deposit tidak terpengaruh. Defaultnya true."
          },
          "allow_self_declaration": {
            "type": "boolean",
            "description": "Jika true, widget kepemilikan dompet menawarkan deklarasi mandiri sebagai metode bukti cadangan. Defaultnya true."
          },
          "allow_screenshot_proof": {
            "type": "boolean",
            "description": "Jika true, widget kepemilikan dompet menawarkan unggahan tangkapan layar sebagai metode bukti kepemilikan. Defaultnya true."
          },
          "auto_wallet_verification": {
            "type": "boolean",
            "description": "Jika true, mengirimkan transfer keluar Travel Rule yang memerlukan bukti kontrol dompet oleh pengguna akhir akan secara otomatis membuat sesi widget kepemilikan dompet yang terikat pada transaksi dan menampilkannya di blok action_required transaksi tersebut. Defaultnya true."
          },
          "vasp_attribution_enabled": {
            "type": "boolean",
            "description": "Jika true, transfer keluar Travel Rule yang tidak dapat dirutekan oleh rail mana pun diatribusikan melalui analitik blockchain: dompet tujuan diidentifikasi ke VASP pemiliknya, entitas tersebut dicatat pada transfer dan di direktori VASP, dan rail dijalankan kembali satu kali dengan nama yang diatribusikan. Defaultnya true."
          },
          "counterparty_screening_enabled": {
            "type": "boolean",
            "description": "Skrining sanksi dan media negatif opsional (opt-in) untuk VASP pihak lawan, ditagihkan per skrining sesuai harga Skrining AML Perusahaan. Saat aktif, Didit menyaring pihak lawan yang dijangkau oleh bursa pengirim (menggunakan kembali skrining yang berusia kurang dari 30 hari) dan Anda dapat menyaringnya dengan POST /v3/travel-rule/vasps/{vasp_id}/screening/. Default false: tidak ada yang diskrining atau ditagihkan."
          },
          "sunrise_policy": {
            "type": "string",
            "enum": [
              "",
              "HOLD",
              "REJECT",
              "PROCEED"
            ],
            "description": "Tindakan yang diambil terhadap transaksi saat transfer kedaluwarsa jika pihak lawan adalah entri direktori di yurisdiksi dalam sunrise_jurisdictions, yang belum menegakkan Travel Rule: HOLD memindahkannya ke peninjauan, REJECT menolaknya, PROCEED membiarkan statusnya tidak berubah. Kosong (default) mengikuti timeout_outcome. Berlaku sebelum non_responsive_policy."
          },
          "sunrise_jurisdictions": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "readOnly": true,
            "description": "Hanya-baca. Negara-negara (ISO 3166 alpha-2) yang diperlakukan Didit berada dalam periode sunrise Travel Rule, tempat sunrise_policy berlaku. Saat ini CO, KH, dan VN. Yurisdiksi lainnya, serta yurisdiksi yang kosong atau tidak dikenal, mengikuti timeout_outcome."
          },
          "non_responsive_policy": {
            "type": "string",
            "enum": [
              "",
              "HOLD",
              "REJECT",
              "PROCEED"
            ],
            "description": "Tindakan yang diambil terhadap transaksi saat transfer kedaluwarsa jika pihak lawan adalah entri direktori yang tingkat responsifnya UNRESPONSIVE: HOLD, REJECT, atau PROCEED, seperti halnya timeout_outcome. Kosong (default) mengikuti timeout_outcome. sunrise_policy berlaku terlebih dahulu jika keduanya sesuai."
          },
          "travel_address": {
            "type": "string",
            "description": "Hanya-baca. Travel Address milik VASP Anda sendiri - endpoint pertanyaan TRP masuk yang telah dienkode yang digunakan VASP lain untuk menghubungi Anda. Kosong selama `is_enabled` bernilai false."
          },
          "disabled_networks": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "GTR",
                "TRUST",
                "VERIFYVASP",
                "SYGNA"
              ]
            },
            "description": "Jaringan memilih keluar dari keanggotaan platform. Tidak menonaktifkan keanggotaan Anda sendiri yang terhubung atau menyediakan jaringan yang tidak tersedia.",
            "default": []
          },
          "networks": {
            "type": "object",
            "readOnly": true,
            "description": "Per jaringan, bagaimana aplikasi ini akan mengirim dan mengapa aplikasi ini tidak dapat mengirim. Tidak ada jaringan, termasuk GTR, yang disertakan secara default: jaringan dapat dijangkau melalui keanggotaan terhubung Anda sendiri, atau melalui keanggotaan Didit setelah keanggotaan Didit di jaringan tersebut aktif dan partisipan Anda sendiri di dalamnya aktif. Bukan pemeriksaan status atau pengiriman langsung.",
            "properties": {
              "gtr": {
                "$ref": "#/components/schemas/TravelRuleNetworkState"
              },
              "trust": {
                "$ref": "#/components/schemas/TravelRuleNetworkState"
              },
              "verifyvasp": {
                "$ref": "#/components/schemas/TravelRuleNetworkState"
              },
              "sygna": {
                "$ref": "#/components/schemas/TravelRuleNetworkState"
              }
            }
          },
          "didit_network": {
            "type": "object",
            "readOnly": true,
            "description": "Apakah jaringan Didit mencantumkan profil VASP Anda, sehingga pelanggan Didit lainnya dapat menemukannya di direktori dan menghubunginya melalui jalur INTERNAL, serta setiap ketentuan yang belum terpenuhi.",
            "properties": {
              "listed": {
                "type": "boolean"
              },
              "missing": {
                "type": "array",
                "items": {
                  "type": "string",
                  "enum": [
                    "travel_rule_off",
                    "sandbox_application",
                    "not_discoverable",
                    "legal_name_missing",
                    "compliance_email_missing",
                    "compliance_email_unconfirmed",
                    "excluded_by_staff",
                    "internal_organization"
                  ]
                },
                "description": "Kosong saat tercantum. compliance_email_unconfirmed: kirim konfirmasi dengan POST /v3/travel-rule/settings/compliance-email/confirmation/ dan buka tautan yang dikirim melalui email. excluded_by_staff: Didit menandai aplikasi sebagai uji coba, demo, atau internal."
              },
              "compliance_email_confirmed": {
                "type": "boolean",
                "description": "Apakah compliance_email saat ini telah dikonfirmasi melalui tautan yang dikirimkan melalui email."
              }
            }
          }
        }
      },
      "TravelRuleSettingsUpdate": {
        "type": "object",
        "properties": {
          "is_enabled": {
            "type": "boolean"
          },
          "legal_name": {
            "type": "string",
            "maxLength": 255
          },
          "lei": {
            "type": "string",
            "maxLength": 20
          },
          "jurisdiction": {
            "type": "string",
            "maxLength": 8
          },
          "name_matching_strictness": {
            "type": "string",
            "enum": [
              "NONE",
              "STRICT",
              "CONTAINS",
              "DEFAULT",
              "FUZZY"
            ],
            "description": "`CONTAINS` menerima satu nama yang semua katanya muncul pada nama lainnya."
          },
          "confirmation_timeout_hours": {
            "type": "integer",
            "minimum": 1
          },
          "timeout_outcome": {
            "type": "string",
            "enum": [
              "HOLD",
              "REJECT",
              "PROCEED"
            ]
          },
          "compliance_email": {
            "type": "string",
            "format": "email",
            "description": "Email kontak kepatuhan untuk profil VASP Anda. Jaringan Didit mencantumkan profil Anda hanya setelah alamat ini dikonfirmasi melalui tautan yang dikirimkan melalui email (POST /v3/travel-rule/settings/compliance-email/confirmation/); mengubahnya memerlukan konfirmasi baru."
          },
          "is_discoverable": {
            "type": "boolean",
            "description": "Menentukan apakah profil VASP Anda dapat dicantumkan dalam jaringan Didit: ditemukan di GET /v3/travel-rule/vasps/ oleh pelanggan Didit lainnya dan dijangkau di rail INTERNAL. Pencantuman juga memerlukan aplikasi produksi, Travel Rule aktif, nama resmi, dan email kepatuhan yang dikonfirmasi; didit_network menyatakan mana yang belum lengkap. Nilai defaultnya adalah true."
          },
          "threshold_amount": {
            "type": "string",
            "description": "String desimal, nol atau lebih besar, dalam mata uang default aplikasi Anda. Jumlah transfer minimum yang memicu pertukaran terkelola."
          },
          "ownership_validation_mode": {
            "type": "string",
            "enum": [
              "FULL",
              "SIMPLIFIED",
              "AUTOMATED"
            ],
            "description": "Lihat kolom respons dengan nama yang sama."
          },
          "simplified_validation_threshold": {
            "type": "string",
            "description": "String desimal, 0 atau lebih."
          },
          "data_sharing_fields": {
            "allOf": [
              {
                "$ref": "#/components/schemas/TravelRuleDataSharingFields"
              }
            ],
            "description": "Digabungkan per jenis entitas: jenis entitas yang Anda lewatkan akan mempertahankan pilihan saat ininya. Pilihan yang tidak dapat memenuhi kewajiban pengirim dari rezim `jurisdiction` Anda (EU TFR atau FATF Recommendation 16), termasuk daftar kosong, akan ditolak dengan `400`."
          },
          "matching_rules": {
            "allOf": [
              {
                "$ref": "#/components/schemas/TravelRuleMatchingRules"
              }
            ],
            "description": "Digabungkan per jenis entitas, dan per kolom di dalamnya. Kolom yang tidak dibandingkan oleh jenis entitas tersebut (misalnya `date_of_birth` untuk `company`) akan ditolak dengan `400`."
          },
          "inbound_auto_accept": {
            "type": "boolean"
          },
          "allow_self_declaration": {
            "type": "boolean"
          },
          "allow_screenshot_proof": {
            "type": "boolean",
            "description": "Jika true, widget kepemilikan dompet menawarkan unggahan tangkapan layar sebagai metode bukti kepemilikan. Defaultnya true."
          },
          "auto_wallet_verification": {
            "type": "boolean"
          },
          "vasp_attribution_enabled": {
            "type": "boolean"
          },
          "counterparty_screening_enabled": {
            "type": "boolean",
            "description": "Skrining sanksi dan media negatif opsional (opt-in) untuk VASP pihak lawan, ditagihkan per skrining sesuai harga Skrining AML Perusahaan. Saat aktif, Didit menyaring pihak lawan yang dijangkau oleh bursa pengirim (menggunakan kembali skrining yang berusia kurang dari 30 hari) dan Anda dapat menyaringnya dengan POST /v3/travel-rule/vasps/{vasp_id}/screening/. Default false: tidak ada yang diskrining atau ditagihkan."
          },
          "sunrise_policy": {
            "type": "string",
            "enum": [
              "",
              "HOLD",
              "REJECT",
              "PROCEED"
            ],
            "description": "HOLD, REJECT, PROCEED, atau kosong untuk mengikuti timeout_outcome. Lihat kolom respons dengan nama yang sama."
          },
          "non_responsive_policy": {
            "type": "string",
            "enum": [
              "",
              "HOLD",
              "REJECT",
              "PROCEED"
            ],
            "description": "HOLD, REJECT, PROCEED, atau kosong untuk mengikuti timeout_outcome. Lihat kolom respons dengan nama yang sama."
          },
          "disabled_networks": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "GTR",
                "TRUST",
                "VERIFYVASP",
                "SYGNA"
              ]
            },
            "description": "Jaringan memilih keluar dari keanggotaan platform. Tidak menonaktifkan keanggotaan Anda sendiri yang terhubung atau menyediakan jaringan yang tidak tersedia.",
            "default": []
          }
        },
        "description": "Semua kolom bersifat opsional; PUT menerapkan pembaruan parsial."
      },
      "WalletAddressEntry": {
        "type": "object",
        "properties": {
          "uuid": {
            "type": "string",
            "format": "uuid"
          },
          "address": {
            "type": "string",
            "description": "Alamat dompet; `\"\"` untuk entri yang diimpor hanya berdasarkan hash-nya. Unik per aplikasi, rantai, dan memo, dengan membandingkan alamat tanpa memperhatikan huruf besar/kecil. Setelah Anda menghapus entri, Anda dapat mendaftarkan alamat yang sama lagi."
          },
          "chain": {
            "type": "string",
            "description": "Token chain untuk alamat, misalnya `ETH` atau `BTC`. Saat Didit merutekan atau mendaftarkan transfer, Didit mencocokkan entri buku alamat pada alamat dompet dan, jika transfer menyertakan chain, pada nilai ini juga, mengabaikan perbedaan huruf besar/kecil. Chain suatu transfer adalah `beneficiary_data.chain`, diisi dari chain kripto atau simbol mata uang transaksi (misalnya `ETH`) saat Anda tidak mengirimkannya, atau `chain` dari pendaftaran pascadeposit, jadi gunakan token yang sama di mana saja. Entri dengan chain kosong cocok dengan chain mana pun. Penerima pembayaran Lightning (ID node atau Lightning Address) yang terdaftar di bitcoin disimpan dalam huruf kecil pada `LIGHTNING`, tempat transfer Lightning dicocokkan. Chain yang dikenal disimpan di bawah satu pengidentifikasi kanonik apa pun ejaan yang Anda kirimkan: \"ethereum\", \"Ethereum\", dan \"ERC20\" semuanya disimpan sebagai ETH, \"BNB Smart Chain\" dan \"BEP20\" sebagai BNB, \"tron\" sebagai TRX. Nama chain yang tidak dikenal disimpan sebagaimana diberikan."
          },
          "holder_vendor_data": {
            "type": "string",
            "description": "Pengenal internal Anda untuk pemegang."
          },
          "holder_name": {
            "type": "string",
            "description": "Nama pemegang dompet, digunakan untuk pencocokan nama penerima."
          },
          "entity_type": {
            "type": "string",
            "description": "Teks bebas, secara default bernilai \"individual\"."
          },
          "is_ownership_verified": {
            "type": "boolean",
            "description": "Hanya-baca. Apakah kepemilikan alamat ini telah terbukti."
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "travel_address": {
            "type": "string",
            "description": "Travel Address milik VASP pihak lawan untuk dompet ini, jika diketahui. Memungkinkan Didit merutekan transfer penerima ini melalui jalur TRP, untuk aset yang didukung TRP (BTC, ETH, dan USDC pada jaringan yang disebutkan)."
          },
          "address_hash": {
            "type": "string",
            "description": "Hanya-baca. SHA-256 dari alamat yang diubah menjadi huruf kecil, dalam heksadesimal huruf kecil. Entri yang diimpor hanya berdasarkan hash-nya akan dicocokkan pada nilai ini."
          },
          "memo": {
            "type": "string",
            "description": "Destination tag atau memo yang merupakan bagian dari dompet di jaringan memo (XRP, XLM, EOS, ATOM, HBAR); `\"\"` untuk seluruh alamat. Entri dengan memo hanya cocok dengan transfer yang mencantumkan memo tersebut; entri tanpa memo cocok dengan seluruh alamat."
          },
          "receiving_travel_address": {
            "type": "string",
            "readOnly": true,
            "description": "Travel Address per-dompet Anda untuk dompet ini: berikan kepada VASP pengirim agar permintaan TRP-nya menyebut dompet ini. Kosong untuk dompet yang tercatat sebagai milik VASP lain, saat Travel Rule dinonaktifkan, dan sebelum profil VASP Anda disimpan."
          }
        }
      },
      "WalletAddressEntryCreate": {
        "type": "object",
        "required": [
          "address"
        ],
        "properties": {
          "address": {
            "type": "string",
            "maxLength": 128,
            "description": "Alamat dompet. Alamat X XRP disimpan sebagai alamat klasik dan tag-nya, sehingga cocok dengan transfer yang mencantumkan salah satu bentuk tersebut."
          },
          "chain": {
            "type": "string",
            "maxLength": 32,
            "description": "Token chain untuk alamat, misalnya `ETH` atau `BTC`. Ketika Didit merutekan atau mendaftarkan transfer, Didit mencocokkan entri buku alamat pada alamat dompet dan, jika transfer membawa chain, pada nilai ini juga, dengan mengabaikan huruf besar/kecil. Chain dari transfer adalah `beneficiary_data.chain`, diisi dari chain kripto transaksi atau simbol mata uang (misalnya `ETH`) jika Anda tidak mengirimkannya, atau `chain` dari pendaftaran setelah deposit, jadi gunakan token yang sama di semua tempat. Entri dengan chain kosong cocok dengan chain apa pun. Chain yang dikenal disimpan di bawah satu pengidentifikasi kanonis apa pun ejaan yang Anda kirimkan: \"ethereum\", \"Ethereum\", dan \"ERC20\" semuanya disimpan sebagai ETH, \"BNB Smart Chain\" dan \"BEP20\" sebagai BNB, \"tron\" sebagai TRX. Nama chain yang tidak dikenal disimpan sebagaimana diberikan."
          },
          "holder_vendor_data": {
            "type": "string",
            "maxLength": 255
          },
          "holder_name": {
            "type": "string",
            "maxLength": 255
          },
          "entity_type": {
            "type": "string",
            "default": "individual",
            "maxLength": 16
          },
          "self_declared": {
            "type": "boolean",
            "default": false,
            "description": "Hanya-tulis. Jika true, entri dibuat dalam keadaan kepemilikannya sudah diverifikasi melalui bukti SELF_DECLARATION. Mengembalikan 400 ketika `allow_self_declaration` dinonaktifkan di pengaturan Travel Rule Anda."
          },
          "travel_address": {
            "type": "string",
            "description": "Opsional. Travel Address VASP pihak lawan untuk dompet ini, yang mengaktifkan perutean TRP untuk aset yang didukung TRP (BTC, ETH, dan USDC pada jaringan yang disebutkan). Travel Address yang tidak valid mengembalikan 400.",
            "maxLength": 512
          },
          "memo": {
            "type": "string",
            "maxLength": 256,
            "description": "Opsional. Tag tujuan atau memo yang merupakan bagian dari dompet. XRP: tag tujuan, bilangan bulat dari 0 hingga 4294967295 (angka JSON diterima). XLM: memo teks hingga 28 byte, ID 64-bit, atau hash 32-byte dalam hex. EOS: hingga 256 byte. ATOM: hingga 256 karakter. HBAR: hingga 100 byte. Dompet Bitcoin, EVM, Solana, Tron, Litecoin, Bitcoin Cash, Dogecoin, dan Lightning tidak menerima memo: jika disertakan akan menghasilkan `400`. Alias: `destinationTag` atau `destination_tag`."
          }
        }
      },
      "WalletAddressEntryUpdate": {
        "type": "object",
        "properties": {
          "holder_name": {
            "type": "string",
            "maxLength": 255
          },
          "holder_vendor_data": {
            "type": "string",
            "maxLength": 255
          },
          "entity_type": {
            "type": "string",
            "maxLength": 16
          },
          "travel_address": {
            "type": "string",
            "maxLength": 512
          }
        },
        "description": "PATCH adalah pembaruan parsial; respons hanya menampilkan holder_name, holder_vendor_data, entity_type, travel_address, receiving_travel_address, label, dan owner_type."
      },
      "TravelRuleTransferDetail": {
        "type": "object",
        "description": "Objek transfer lengkap yang dikembalikan oleh endpoint konfirmasi kepemilikan dan penyelesaian/pembatalan. Selama kepemilikan dompet transfer masuk belum dikonfirmasi, `originator_data` dan `beneficiary_data` pihak lawan akan dikembalikan dalam kondisi disamarkan (huruf pertama dari setiap kata dipertahankan; dompet, blockchain, dan perutean VASP tetap dapat dibaca) dan `data_masked` bernilai true.",
        "properties": {
          "uuid": {
            "type": "string",
            "format": "uuid"
          },
          "status": {
            "type": "string",
            "enum": [
              "AWAITING_COUNTERPARTY",
              "ON_HOLD",
              "COMPLETED",
              "FINISHED",
              "CANCELLED",
              "EXPIRED",
              "COUNTERPARTY_MISMATCHED_DATA",
              "COUNTERPARTY_VASP_NOT_FOUND",
              "COUNTERPARTY_VASP_NOT_REACHABLE",
              "UNCONFIRMED_OWNERSHIP",
              "COUNTERPARTY_VASP_GENERAL_DECLINE",
              "NOT_ENOUGH_COUNTERPARTY_DATA",
              "NOT_APPLICABLE"
            ]
          },
          "direction": {
            "type": "string",
            "enum": [
              "INBOUND",
              "OUTBOUND"
            ]
          },
          "rail": {
            "type": "string",
            "nullable": true,
            "enum": [
              "INTERNAL",
              "TRP",
              "GTR",
              "TRUST",
              "VERIFYVASP",
              "SYGNA",
              "EMAIL",
              "TEST_VASP",
              null
            ],
            "description": "Jalur yang digunakan untuk merutekan transfer, atau null ketika tidak ada jalur yang dipilih (misalnya di bawah ambang batas, dompet pihak lawan swakelola, registrasi setelah deposit, atau tidak ada pihak lawan yang dapat dijangkau). INTERNAL berarti kedua belah pihak adalah aplikasi Didit; EMAIL berarti pihak lawan dijangkau melalui tautan pengambilan yang dikirim lewat email. TEST_VASP berarti Test VASP Didit merespons transfer sandbox. Melalui GTR, VERIFYVASP, dan SYGNA, Didit membaca jawaban pihak lawan dari respons jaringan atau dengan melakukan polling setiap 5 menit. TRUST hanya mengirim, sehingga transfer TRUST tetap berstatus AWAITING_COUNTERPARTY hingga kedaluwarsa. Jalur jaringan hanya digunakan ketika Anda telah menghubungkan keanggotaan Anda sendiri untuk jaringan tersebut. Jalur dipilih setelah pembuatan transaksi menghasilkan respons, sehingga nilainya null dalam respons tersebut."
          },
          "protocol": {
            "type": "string",
            "nullable": true
          },
          "ivms_version": {
            "type": "string",
            "example": "ivms101.2023"
          },
          "required": {
            "type": "boolean"
          },
          "ownership_confirmed": {
            "type": "boolean",
            "nullable": true
          },
          "deadline_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "timeline": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "status": {
                  "type": "string"
                },
                "at": {
                  "type": "string",
                  "format": "date-time"
                },
                "detail": {
                  "type": "string"
                },
                "name_match": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/TravelRuleNameMatch"
                    }
                  ],
                  "nullable": true,
                  "description": "Perbandingan nama yang diputuskan oleh entri ini, di samping `detail`. Tidak ada pada entri yang tidak membandingkan nama."
                },
                "reason": {
                  "type": "string",
                  "description": "Hadir hanya pada entri transisi yang disebabkan oleh pengiriman yang gagal: `email_undeliverable` atau `delivery_failed`, nilai yang dilaporkan oleh `reason` transfer."
                }
              }
            }
          },
          "counterparty_vasp": {
            "type": "object",
            "nullable": true,
            "properties": {
              "name": {
                "type": "string"
              },
              "lei": {
                "type": "string"
              },
              "dd_score": {
                "type": "integer",
                "description": "Skor uji tuntas dari 0 hingga 100, dengan nilai lebih tinggi lebih baik. Skala yang sama seperti dalam direktori VASP."
              },
              "dd_score_breakdown": {
                "type": "object",
                "description": "Kontribusi per komponen ke dd_score, satu objek per komponen seperti di direktori VASP (jurisdiction, verification, protocol, lei, history, essentials, responsiveness), masing-masing {points, max, reason, detail}. {} sampai pihak lawan telah dinilai.",
                "additionalProperties": {
                  "type": "object",
                  "properties": {
                    "points": {
                      "type": "number",
                      "description": "Poin yang diberikan untuk komponen ini."
                    },
                    "max": {
                      "type": "integer",
                      "description": "Poin maksimum yang dapat diberikan komponen ini."
                    },
                    "reason": {
                      "type": "string",
                      "description": "Kode yang dapat dibaca mesin untuk keputusan komponen."
                    },
                    "detail": {
                      "type": "string",
                      "description": "Alasan yang dapat dibaca manusia atas poin yang diberikan."
                    }
                  }
                }
              },
              "dd_assessed_at": {
                "type": "string",
                "format": "date-time",
                "nullable": true,
                "description": "Waktu ketika penilaian uji tuntas terakhir kali dijalankan. Null hingga pihak lawan telah dinilai."
              }
            }
          },
          "originator_data": {
            "type": "object",
            "description": "Pihak pengirim. Untuk transfer masuk, nilai pihak lawan disamarkan sampai kepemilikan dikonfirmasi."
          },
          "beneficiary_data": {
            "type": "object",
            "description": "Pihak penerima. Untuk transfer masuk, nilai pihak lawan disamarkan hingga kepemilikan dikonfirmasi."
          },
          "name_match": {
            "allOf": [
              {
                "$ref": "#/components/schemas/TravelRuleNameMatch"
              }
            ],
            "nullable": true,
            "description": "Perbandingan nama yang menentukan transfer, atau null hingga perbandingan dijalankan. Saat para pihak disamarkan, dan pada salinan pertukaran INTERNAL milik pelanggan lain, `transfer_name`, `compared_name`, `matched_names`, dan `mismatched_names` disembunyikan. `score` dan `matched` bisa tidak sejalan: `matched` mengikuti tingkat ketatnya, sedangkan `score` adalah kesamaan dari kedua nama lengkap tersebut."
          },
          "data_match": {
            "$ref": "#/components/schemas/TravelRuleDataMatch"
          },
          "mismatched_fields": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Pintasan untuk `data_match.mismatched_fields`. Kosong jika tidak ada perbedaan."
          },
          "data_unmasked": {
            "$ref": "#/components/schemas/TravelRuleDataUnmasked"
          },
          "data_masked": {
            "type": "boolean",
            "description": "True selama data pribadi pihak lawan disamarkan dalam respons ini."
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "delivery": {
            "nullable": true,
            "allOf": [
              {
                "$ref": "#/components/schemas/TravelRuleDelivery"
              }
            ],
            "description": "Status pesan terbaru yang harus dikirimkan transfer ini ke pihak lain. Bernilai null jika transfer tidak pernah diharuskan mengirimkannya (misalnya di bawah `threshold_amount`, dompet swakelola yang dideklarasikan, atau registrasi sunrise)."
          },
          "discovery": {
            "type": "array",
            "description": "Cara Didit mencari pihak lawan, satu entri per langkah yang dijalankan. Kosong jika tidak ada penemuan yang dijalankan, misalnya pada transfer masuk.",
            "items": {
              "$ref": "#/components/schemas/TravelRuleDiscoveryStep"
            }
          },
          "reason": {
            "type": "string",
            "description": "Alasan transfer `COUNTERPARTY_VASP_NOT_FOUND` atau `COUNTERPARTY_VASP_NOT_REACHABLE` tertahan; `\"\"` untuk status lainnya. Pengiriman yang gagal menentukannya terlebih dahulu, hanya pada `COUNTERPARTY_VASP_NOT_REACHABLE`: `email_undeliverable` (penyedia email menolak email kepatuhan dan tidak ada alamat tersisa untuk dicoba: saat dikirim, pada pengingat, atau sebagai pantulan permanen yang dilaporkan kemudian) atau `delivery_failed` (jalur pengiriman gagal total: jalur jaringan menolak pesan atau kehabisan percobaan coba lagi, host identitas `TRP` tidak menjawab, atau host `TRP` pihak lawan tidak menerima permintaan informasi). Jika tidak, jejak `discovery` yang menentukannya: `awaiting_end_user` (tidak ada langkah yang menyebutkan pihak lawan yang dapat dijangkau Didit), `directory_match_no_route` (suatu langkah menyebutkan VASP direktori yang tidak memiliki rute), `picked_member_without_proven_wallet` (pengguna akhir memilih pelanggan Didit yang belum membuktikan kendali atas dompet), atau `no_directory_match` saat jejak tidak memberikan alasan lain. Pengiriman ulang akan memajukan transfer, sehingga alasannya dihapus. Lihat [Mengapa transfer tertahan](/id/transaction-monitoring/travel-rule#mengapa-transfer-macet)."
          },
          "next_actions": {
            "type": "array",
            "description": "Apa yang melanjutkan transfer; `[]` untuk status apa pun selain `COUNTERPARTY_VASP_NOT_FOUND` atau `COUNTERPARTY_VASP_NOT_REACHABLE`. `email_undeliverable` menawarkan `update_compliance_email`, lalu `resend`. `delivery_failed` menawarkan `resend`. Alasan penemuan menawarkan `select_counterparty_vasp`, `declare_self_hosted`, `add_vasp_hint`, dan `resend`.",
            "items": {
              "$ref": "#/components/schemas/TravelRuleNextAction"
            }
          },
          "chain_details": {
            "$ref": "#/components/schemas/TravelRuleChainDetails"
          }
        }
      },
      "TravelRuleOwnershipConfirmRequest": {
        "type": "object",
        "required": [
          "confirmed"
        ],
        "properties": {
          "confirmed": {
            "type": "boolean",
            "description": "true untuk mengonfirmasi kepemilikan, false untuk menolaknya."
          },
          "wallet_address": {
            "type": "string",
            "default": "",
            "description": "Transfer TRP masuk: alamat pembayaran yang dikembalikan Didit ke VASP pengirim saat Anda menyetujuinya. Default-nya adalah alamat entri buku alamat yang cocok, lalu beneficiary_data.wallet_address. Pada transfer dompet swakelola yang dideklarasikan yang tidak menyebutkan dompet pihak lawan, dompet yang kepemilikannya Anda verifikasi; tanpanya permintaan ditolak dengan 400. Diabaikan untuk transfer lainnya."
          }
        }
      },
      "TravelRuleTransferPatchRequest": {
        "type": "object",
        "description": "Sediakan tepat salah satu dari: payment_txn_id (finish), action=cancel, action=resend, action=update_compliance_email dengan compliance_email, action=update_originator_wallet dengan wallet_address, atau action=beneficiary_vasp dengan beneficiary_vasp.",
        "properties": {
          "payment_txn_id": {
            "type": "string",
            "description": "Hash transaksi on-chain. Mengharuskan transfer berupa transfer keluar dengan status COMPLETED."
          },
          "action": {
            "type": "string",
            "enum": [
              "cancel",
              "resend",
              "update_compliance_email",
              "update_originator_wallet",
              "beneficiary_vasp"
            ],
            "description": "\"cancel\" membatalkan transfer non-terminal. \"resend\" menjalankan ulang perutean untuk transfer keluar yang tertahan di COUNTERPARTY_VASP_NOT_FOUND, COUNTERPARTY_VASP_NOT_REACHABLE, atau NOT_ENOUGH_COUNTERPARTY_DATA. \"update_compliance_email\" mengganti email kepatuhan yang menjadi tujuan permintaan, pada transfer keluar di salah satu dari tiga status tersebut; kirim \"resend\" setelahnya. \"update_originator_wallet\" mencatat dompet tempat dana sebenarnya keluar (`wallet_address`, `memo`). \"beneficiary_vasp\" menentukan sendiri VASP pihak lawan (memerlukan `beneficiary_vasp`) untuk transfer keluar di salah satu status tersebut: transfer akan dirutekan ke VASP tersebut dan dikirim lagi."
          },
          "compliance_email": {
            "type": "string",
            "format": "email",
            "maxLength": 254,
            "description": "Wajib diisi dengan `action: update_compliance_email`. Disimpan sebagai `beneficiary_data.counterparty_vasp_email` transfer ini: data ini hanya milik transfer ini dan tidak dimasukkan ke entri direktori atau daftar kontak mana pun."
          },
          "wallet_address": {
            "type": "string",
            "maxLength": 128,
            "description": "Dengan `action: update_originator_wallet`: dompet asal dana keluar. Ketika input UTXO transfer diketahui, dompet tersebut harus merupakan salah satunya."
          },
          "memo": {
            "type": "string",
            "maxLength": 256,
            "description": "Dengan `action: update_originator_wallet`: memo atau tag dompet pada jaringan memo. Opsional."
          },
          "beneficiary_vasp": {
            "type": "string",
            "format": "uuid",
            "description": "Wajib diisi dengan action=beneficiary_vasp: `id` dari VASP direktori, dari `GET /v3/travel-rule/vasps/`. Pilihan Anda lebih diutamakan daripada setiap langkah penemuan otomatis, yang tidak akan pernah menimpanya."
          }
        }
      },
      "VaspDirectoryEntry": {
        "type": "object",
        "description": "VASP dari direktori atau anggota jaringan Didit, beserta rute yang dimiliki aplikasi Anda ke VASP tersebut. Pelanggan adalah anggota jaringan Didit hanya selama aplikasinya berstatus aktif, Travel Rule aktif, profilnya dapat ditemukan, memiliki nama resmi dan email kepatuhan yang telah dikonfirmasi, serta Didit belum menandai aplikasi tersebut sebagai aplikasi uji coba, demo, atau internal. Setiap baris juga memuat penilaian uji tuntas bersama (dd_score, risk_level, responsiveness, essential_checks) serta keputusan, skrining entitas, dan kuesioner aplikasi Anda sendiri, yang tidak dapat dilihat oleh pelanggan lain.",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "ID entri, untuk GET /v3/travel-rule/vasps/{vasp_id}/."
          },
          "kind": {
            "type": "string",
            "enum": [
              "directory",
              "didit"
            ],
            "description": "directory untuk entri direktori bersama; didit untuk anggota jaringan Didit."
          },
          "name": {
            "type": "string"
          },
          "lei": {
            "type": "string"
          },
          "jurisdiction": {
            "type": "string",
            "description": "Kode negara ISO 3166, sesuai yang diberikan oleh sumber."
          },
          "domains": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Domain web VASP. Selalu kosong untuk anggota jaringan Didit."
          },
          "reachable": {
            "type": "boolean",
            "description": "Menentukan apakah aplikasi Anda memiliki rute yang tersedia ke VASP ini, atau ke salah satu entitasnya untuk suatu merek. Selalu true untuk anggota jaringan Didit, kecuali pada aplikasi sandbox, di mana setiap baris bernilai false."
          },
          "aliases": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "name": {
                  "type": "string"
                },
                "kind": {
                  "type": "string",
                  "enum": [
                    "trading_name",
                    "other_legal_name",
                    "network_name",
                    "attribution",
                    "merged",
                    "staff"
                  ],
                  "description": "trading_name, other_legal_name (dari daftar LEI global), network_name (nama pada jaringan Travel Rule), attribution (nama entitas yang diberikan analitik blockchain untuk dompet VASP), merged (nama entri duplikat yang digabungkan ke entri ini) atau staff."
                }
              }
            },
            "description": "Nama lain yang digunakan untuk mengidentifikasi VASP."
          },
          "networks": {
            "type": "array",
            "items": {
              "type": "object",
              "description": "Daftar terkini dari VASP ini di direktori anggota jaringan Travel Rule. Daftar TRISA menyatakan siapa VASP tersebut di TRISA; Didit tidak memiliki rel TRISA, sehingga tidak pernah menjadi rute.",
              "properties": {
                "network": {
                  "type": "string",
                  "enum": [
                    "GTR",
                    "TRUST",
                    "VERIFYVASP",
                    "SYGNA",
                    "TRISA"
                  ]
                },
                "code": {
                  "type": "string",
                  "description": "Pengidentifikasi VASP pada jaringan tersebut."
                },
                "listed_name": {
                  "type": "string",
                  "description": "Nama yang digunakan jaringan untuk mencantumkan VASP."
                },
                "country": {
                  "type": "string",
                  "description": "Negara yang dicantumkan jaringan, jika menyediakannya."
                },
                "verified_at": {
                  "type": "string",
                  "format": "date-time",
                  "nullable": true,
                  "description": "Waktu ketika staf Didit memverifikasi listing tersebut. Bernilai null untuk listing yang dibaca dari direktori publik."
                },
                "last_seen_at": {
                  "type": "string",
                  "format": "date-time",
                  "nullable": true,
                  "description": "Waktu sumber terakhir menampilkan daftar. Daftar yang tidak ditampilkan oleh sumber selama tiga minggu akan dihapus."
                },
                "source": {
                  "type": "string",
                  "enum": [
                    "trisa_directory",
                    "staff"
                  ],
                  "description": "Asal listing: direktori publik TRISA, atau staf Didit."
                }
              }
            }
          },
          "routes": {
            "type": "array",
            "items": {
              "type": "object",
              "description": "Satu cara aplikasi Anda dapat mengirimkan data Travel Rule ke VASP ini, sesuai urutan percobaan pengiriman. Rute jaringan memerlukan keanggotaan pada jaringan tersebut: milik Anda sendiri (terhubung di Marketplace) atau milik Didit setelah Didit memilikinya. Tanpanya rute akan dicantumkan sebagai tidak tersedia beserta alasannya, tidak pernah sebagai cara untuk menghubungi VASP.",
              "properties": {
                "rail": {
                  "type": "string",
                  "enum": [
                    "INTERNAL",
                    "TRP",
                    "GTR",
                    "TRUST",
                    "VERIFYVASP",
                    "SYGNA",
                    "EMAIL"
                  ]
                },
                "status": {
                  "type": "string",
                  "enum": [
                    "available",
                    "unavailable"
                  ]
                },
                "reason": {
                  "type": "string",
                  "enum": [
                    "",
                    "no_membership",
                    "network_switched_off",
                    "sandbox_application"
                  ],
                  "description": "Alasan mengapa rute yang tidak tersedia tidak dapat digunakan: no_membership (baik Anda maupun Didit tidak memiliki keanggotaan di jaringan tersebut), network_switched_off (Anda menonaktifkan jaringan tersebut di pengaturan Anda), atau sandbox_application (aplikasi sandbox hanya mengirim ke Didit Test VASP, sehingga tidak ada rute yang tersedia untuknya). Kosong jika rute tersedia."
                },
                "via": {
                  "type": "string",
                  "enum": [
                    "",
                    "own_membership",
                    "didit_membership",
                    "directory",
                    "contact",
                    "didit_network"
                  ],
                  "description": "Cara mencapai rute yang tersedia: own_membership atau didit_membership untuk rail jaringan, directory untuk endpoint TRP yang diverifikasi direktori, contact untuk rail EMAIL, didit_network untuk anggota jaringan Didit. Kosong jika rute tidak tersedia."
                }
              }
            }
          },
          "umbrella": {
            "type": "object",
            "nullable": true,
            "description": "Brand yang menaungi entitas teregulasi ini. Null jika bukan bagian dari salah satunya.",
            "properties": {
              "id": {
                "type": "string",
                "format": "uuid"
              },
              "name": {
                "type": "string"
              }
            }
          },
          "entities": {
            "type": "array",
            "items": {
              "type": "object",
              "description": "Entitas teregulasi dari suatu merek: entitas hukum yang menerima transfer.",
              "properties": {
                "id": {
                  "type": "string",
                  "format": "uuid"
                },
                "name": {
                  "type": "string"
                },
                "lei": {
                  "type": "string"
                },
                "jurisdiction": {
                  "type": "string"
                },
                "reachable": {
                  "type": "boolean",
                  "description": "Menentukan apakah aplikasi Anda memiliki rute yang tersedia ke entitas tersebut."
                }
              }
            },
            "description": "Untuk sebuah merek, entitas teregulasi yang menerima transfernya. Transfer yang menyebutkan merek tersebut akan diarahkan ke entitas yang dapat dijangkau di yurisdiksi yang dinyatakannya (beneficiary_data.counterparty_vasp_jurisdiction), jika tidak ada maka ke atribusi analitik blockchain entitas yang ditautkan ke dompet tujuan, jika tidak ada maka ke satu-satunya entitas yang dapat dijangkau ketika tidak ada yurisdiksi yang dinyatakan. Dua entitas yang sama-sama cocok tidak pernah ditebak salah satunya."
          },
          "contacts": {
            "type": "array",
            "items": {
              "type": "object",
              "description": "Kontak kepatuhan yang dapat dikirimi pesan oleh rel EMAIL.",
              "properties": {
                "id": {
                  "type": "string",
                  "format": "uuid"
                },
                "email": {
                  "type": "string",
                  "format": "email"
                },
                "name": {
                  "type": "string"
                },
                "source": {
                  "type": "string",
                  "enum": [
                    "staff",
                    "application",
                    "learned"
                  ],
                  "description": "staff: dikurasi oleh Didit; application: ditambahkan oleh aplikasi Anda; learned: alamat yang menjawab permintaan Travel Rule melalui tautan responsnya."
                },
                "scope": {
                  "type": "string",
                  "enum": [
                    "platform",
                    "application"
                  ],
                  "description": "kontak platform digunakan untuk transfer setiap pelanggan Didit; kontak aplikasi bersifat privat untuk aplikasi Anda, yang hanya melihat miliknya sendiri."
                },
                "verified_at": {
                  "type": "string",
                  "format": "date-time",
                  "nullable": true,
                  "description": "Waktu ketika seseorang di alamat ini menjawab permintaan. Null jika belum."
                }
              }
            },
            "description": "Kontak platform untuk VASP ini dan kontak milik aplikasi Anda sendiri."
          },
          "dd_status": {
            "type": "string",
            "enum": [
              "NOT_STARTED",
              "IN_PROGRESS",
              "COMPLETED",
              "REJECTED"
            ],
            "description": "Status verifikasi Didit untuk entri tersebut, dinilai berdasarkan komponen verifikasi dari dd_score. Selalu bernilai COMPLETED untuk anggota jaringan Didit."
          },
          "dd_score": {
            "type": "integer",
            "nullable": true,
            "minimum": 0,
            "maximum": 100,
            "description": "Skor uji tuntas bersama dari entri direktori, 0 hingga 100, di mana nilai lebih tinggi lebih aman (lihat dd_score_semantic): jumlah poin dalam dd_score_breakdown. Bernilai null untuk anggota jaringan Didit, yang tidak dinilai. Entri yang belum dinilai (dd_assessed_at bernilai null) menampilkan 0 dengan risk_level kosong, jadi bacalah risk_level daripada skor mentah."
          },
          "reachable_rails": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "INTERNAL",
                "TRP",
                "GTR",
                "TRUST",
                "VERIFYVASP",
                "SYGNA",
                "EMAIL"
              ]
            },
            "description": "Rail yang dicatat pada entri. Baca rute untuk mengetahui apa yang dapat digunakan aplikasi Anda saat ini."
          },
          "is_didit_customer": {
            "type": "boolean",
            "description": "true untuk anggota jaringan Didit (dd_status selalu COMPLETED, dd_score null dan risk_level kosong untuk ini) dan untuk entri direktori yang ditautkan ke pelanggan Didit."
          },
          "dd_score_breakdown": {
            "type": "object",
            "description": "Satu objek per komponen dari dd_score. Komponen, bobotnya (maks), dan kode alasannya: jurisdiction, 25 (jurisdiction_not_high_risk, jurisdiction_high_risk, jurisdiction_unknown); verification, 15 (dd_status_completed, dd_status_in_progress, dd_status_not_started, dd_status_rejected); protocol, 15 (native_rail, email_only, no_rail); lei, 10 (lei_valid, lei_missing); history, 10 (history, no_history); essentials, 15 (essential_checks, no_essential_checks); responsiveness, 10 (responsive, unresponsive, responsiveness_unknown). Kosong untuk anggota jaringan Didit.",
            "additionalProperties": {
              "type": "object",
              "properties": {
                "points": {
                  "type": "number",
                  "description": "Poin yang dikontribusikan komponen, dibulatkan ke satu desimal."
                },
                "max": {
                  "type": "integer",
                  "description": "Bobot komponen: poin maksimal yang dapat diatribusikannya."
                },
                "reason": {
                  "type": "string",
                  "description": "Kode yang dapat dibaca mesin untuk keputusan komponen."
                },
                "detail": {
                  "type": "string",
                  "description": "Penjelasan satu baris dalam bahasa Inggris."
                }
              }
            }
          },
          "dd_assessed_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Waktu ketika dd_score, risk_level, dan responsiveness terakhir dihitung: setelah pertukaran dengan entri tersebut selesai, berakhir, kedaluwarsa, tidak cocok, atau ditolak, saat Didit menyegarkan atau mengkurasi entri tersebut, serta dalam penyegaran direktori mingguan. Null untuk anggota jaringan Didit."
          },
          "dd_score_semantic": {
            "type": "string",
            "enum": [
              "higher_is_safer"
            ],
            "description": "Arah pembacaan dd_score: selalu higher_is_safer."
          },
          "risk_level": {
            "type": "string",
            "enum": [
              "LOW",
              "MEDIUM",
              "HIGH",
              ""
            ],
            "description": "Rentang tempat dd_score berada: LOW (70 atau lebih), MEDIUM (40 hingga 69), atau HIGH (di bawah 40). Kosong untuk anggota jaringan Didit dan untuk entri yang belum dinilai. Gunakan filter risk untuk memfilter nilai ini. Skrining yang Anda tandai sendiri tidak pernah mengubah nilai bersama ini: melainkan menjadikan counterparty_risk_level bernilai HIGH dalam aturan Anda."
          },
          "responsiveness": {
            "type": "object",
            "description": "Apakah VASP merespons permintaan Travel Rule: persentase permintaan yang diajukan oleh pelanggan Didit kepadanya dalam 90 hari terakhir yang direspons. Hanya permintaan yang dikirim melalui jalur jaringan atau protokol, atau melalui email ke alamat bersama (alamat kepatuhan entri atau kontak platform), yang dihitung; permintaan yang dikirim ke alamat yang diketik pelanggan, atau ke kontak pribadi pelanggan, tidak pernah dihitung. Permintaan yang kedaluwarsa dianggap tidak terjawab; pertukaran yang selesai, penolakan, atau ketidakcocokan data dianggap sebagai respons; permintaan yang dibatalkan atau jalur yang tidak dapat dihubungi bukan merupakan keduanya. Selalu UNKNOWN dengan hitungan nol untuk anggota jaringan Didit.",
            "properties": {
              "status": {
                "type": "string",
                "enum": [
                  "RESPONSIVE",
                  "UNRESPONSIVE",
                  "UNKNOWN"
                ],
                "description": "UNKNOWN jika kurang dari 5 permintaan yang diputuskan dalam jendela waktu; UNRESPONSIVE jika kurang dari 10 persen di antaranya terjawab; selain itu RESPONSIVE."
              },
              "answered": {
                "type": "integer",
                "description": "Permintaan yang diputuskan dalam jendela waktu yang dijawab oleh VASP."
              },
              "total": {
                "type": "integer",
                "description": "Permintaan yang diputuskan dalam jendela waktu: yang dijawab ditambah yang kedaluwarsa."
              },
              "computed_at": {
                "type": "string",
                "format": "date-time",
                "nullable": true
              }
            }
          },
          "essential_checks": {
            "type": "object",
            "description": "Laporan pemeriksaan penting (essential-checks) dari suatu entri direktori, yang dibuat hanya dari sumber terverifikasi platform: pendaftaran (registri resmi mencantumkan VASP: registri interim MiCA UE, direktori publik TRISA, atau registri LEI global), lisensi (otorisasi MiCA tercatat dan masih berlaku), domain (domain entri cocok dengan endpoint TRP-nya atau situs web yang tercantum di registrinya), dan lei (rekaman LEI-nya aktif, diterbitkan, dan konsisten dengan nama serta negara entri). Komponen penting dari dd_score adalah proporsi pemeriksaan yang telah diputuskan dan lulus. Kosong hingga pembaruan direktori mingguan pertama kali memeriksa entri tersebut, dan selalu kosong untuk anggota jaringan Didit.",
            "properties": {
              "level": {
                "type": "string",
                "enum": [
                  "essential"
                ]
              },
              "checked_at": {
                "type": "string",
                "format": "date-time"
              },
              "checks": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "enum": [
                        "registration",
                        "licence",
                        "domain",
                        "lei"
                      ]
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "pass",
                        "fail",
                        "unknown"
                      ],
                      "description": "unknown jika tidak ada sumber tercatat yang dapat memutuskan pemeriksaan."
                    },
                    "reason": {
                      "type": "string",
                      "description": "Kode keputusan yang dapat dibaca mesin."
                    },
                    "detail": {
                      "type": "string",
                      "description": "Penjelasan satu baris dalam bahasa Inggris."
                    }
                  }
                }
              },
              "passed": {
                "type": "integer"
              },
              "failed": {
                "type": "integer"
              },
              "unknown": {
                "type": "integer"
              },
              "total": {
                "type": "integer"
              }
            }
          },
          "decision": {
            "allOf": [
              {
                "$ref": "#/components/schemas/TravelRuleCounterpartyDecision"
              }
            ],
            "nullable": true,
            "description": "Keputusan aplikasi Anda terhadap VASP ini, atau untuk entitas yang tidak memiliki keputusan tersendiri, keputusan mereknya (inherited_from menyebutkan nama merek tersebut). Bernilai null jika tidak ada. Bersifat privat untuk aplikasi Anda."
          },
          "entity_screening": {
            "allOf": [
              {
                "$ref": "#/components/schemas/TravelRuleCounterpartyScreening"
              }
            ],
            "nullable": true,
            "description": "Skrining sanksi dan media negatif terbaru dari aplikasi Anda untuk VASP ini. Bernilai null jika Anda belum pernah melakukan skrining. Bersifat privat untuk aplikasi Anda."
          },
          "questionnaires": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TravelRuleCounterpartyQuestionnaire"
            },
            "description": "Kuesioner uji tuntas aplikasi Anda dengan VASP ini, yang terbaru lebih dahulu. Bersifat privat untuk aplikasi Anda."
          }
        },
        "example": {
          "id": "0d6f3c2a-6a1e-4c55-9a39-1f2b0c7d8e91",
          "kind": "directory",
          "name": "Example Counterparty VASP",
          "lei": "529900EXAMPLECPTY001",
          "jurisdiction": "DE",
          "domains": [
            "counterparty.example"
          ],
          "reachable": true,
          "aliases": [
            {
              "name": "Example Counterparty",
              "kind": "trading_name"
            }
          ],
          "networks": [
            {
              "network": "GTR",
              "code": "EXAMPLE01",
              "listed_name": "Example Counterparty VASP",
              "country": "DE",
              "verified_at": "2026-10-12T09:30:00Z",
              "last_seen_at": "2026-10-12T09:30:00Z",
              "source": "staff"
            }
          ],
          "routes": [
            {
              "rail": "GTR",
              "status": "unavailable",
              "reason": "no_membership",
              "via": ""
            },
            {
              "rail": "EMAIL",
              "status": "available",
              "reason": "",
              "via": "contact"
            }
          ],
          "umbrella": null,
          "entities": [],
          "contacts": [
            {
              "id": "6c1f9b8e-2d4a-4f7e-8b3c-5a9d0e1f2a3b",
              "email": "travelrule@counterparty.example",
              "name": "Travel Rule desk",
              "source": "staff",
              "scope": "platform",
              "verified_at": null
            }
          ],
          "dd_status": "NOT_STARTED",
          "dd_score": 62,
          "dd_score_breakdown": {
            "jurisdiction": {
              "points": 25.0,
              "max": 25,
              "reason": "jurisdiction_not_high_risk",
              "detail": "DEU is not on the high-risk jurisdiction list"
            },
            "verification": {
              "points": 3.8,
              "max": 15,
              "reason": "dd_status_not_started",
              "detail": "due diligence status NOT_STARTED"
            },
            "protocol": {
              "points": 6.0,
              "max": 15,
              "reason": "email_only",
              "detail": "reachable over the email fallback only"
            },
            "lei": {
              "points": 10.0,
              "max": 10,
              "reason": "lei_valid",
              "detail": "valid LEI on record"
            },
            "history": {
              "points": 5.0,
              "max": 10,
              "reason": "no_history",
              "detail": "no exchange history"
            },
            "essentials": {
              "points": 7.5,
              "max": 15,
              "reason": "no_essential_checks",
              "detail": "no decided essential check yet"
            },
            "responsiveness": {
              "points": 5.0,
              "max": 10,
              "reason": "responsiveness_unknown",
              "detail": "0 decided recent requests, too few to judge"
            }
          },
          "dd_assessed_at": "2026-10-12T09:30:00Z",
          "dd_score_semantic": "higher_is_safer",
          "risk_level": "MEDIUM",
          "responsiveness": {
            "status": "UNKNOWN",
            "answered": 0,
            "total": 0,
            "computed_at": "2026-10-12T09:30:00Z"
          },
          "essential_checks": {},
          "reachable_rails": [
            "GTR",
            "EMAIL"
          ],
          "is_didit_customer": false,
          "decision": {
            "decision": "APPROVED",
            "reason": "Licensed in DE, questionnaire reviewed",
            "decided_by": "",
            "updated_at": "2026-10-14T10:05:00Z",
            "inherited_from": null
          },
          "entity_screening": {
            "id": "7a1d2c3b-4e5f-4a6b-8c7d-9e0f1a2b3c4d",
            "status": "Approved",
            "total_hits": 0,
            "score": null,
            "screened_at": "2026-10-14T09:58:00Z",
            "fresh": true,
            "flagged": false
          },
          "questionnaires": [
            {
              "id": "8b7a6c5d-4e3f-4a2b-9c1d-0e9f8a7b6c5d",
              "status": "ANSWERED",
              "form_version": "1",
              "sent_to": "travelrule@counterparty.example",
              "sent_at": "2026-09-02T08:00:00Z",
              "expires_at": "2026-10-02T08:00:00Z",
              "answered_at": "2026-09-04T15:20:00Z",
              "valid_until": "2027-09-04T15:20:00Z",
              "current": true,
              "answers": {
                "legal_name": "Example Counterparty VASP, incorporated in the example jurisdiction.",
                "licensing": "Crypto-asset service provider authorised under MiCA by its national regulator, licence active.",
                "jurisdictions": "EU and EEA. We do not serve the United States.",
                "aml_program": "Written AML/CFT policy, annual independent review, last completed in March 2026.",
                "compliance_officer": "Head of Compliance, reachable at compliance@counterparty.example.",
                "sanctions_screening": "Customers at onboarding and daily; counterparties on every transfer.",
                "transaction_monitoring": "Rule-based monitoring with analyst review; suspicious activity reports filed with the FIU.",
                "travel_rule": "TRP and email; we answer requests within one business day.",
                "custody": "Segregated customer wallets held with a qualified custodian, insured.",
                "ownership": "No shareholder holds 25 percent or more; parent company Example Holding Group.",
                "record_keeping": "Five-year record-keeping for Travel Rule and transaction data, as our regulator requires.",
                "data_protection": "Encrypted at rest and in transit, stored in the EU."
              }
            }
          ]
        }
      },
      "TravelRuleCounterpartyDecision": {
        "type": "object",
        "description": "Keputusan aplikasi Anda terhadap VASP pihak lawan. Bersifat privat untuk aplikasi Anda: keputusan ini tidak pernah mengubah entri direktori bersama dan pelanggan lain tidak pernah melihatnya. Keputusan ini hanya berlaku melalui aturan transaksi Anda (kolom aturan counterparty_dd_status serta preset travel-rule-counterparty-blocked dan travel-rule-counterparty-restricted); ini tidak pernah mengubah cara transfer diarahkan.",
        "properties": {
          "decision": {
            "type": "string",
            "enum": [
              "APPROVED",
              "RESTRICTED",
              "BLOCKED"
            ],
            "description": "APPROVED: tim Anda telah menyetujui pihak lawan. RESTRICTED: transfer kepadanya dapat dilanjutkan setelah peninjauan. BLOCKED: tim Anda menolaknya."
          },
          "reason": {
            "type": "string",
            "maxLength": 255,
            "description": "Alasan teks bebas yang Anda berikan, kosong jika tidak ada."
          },
          "decided_by": {
            "type": "string",
            "description": "Pengguna konsol yang membuat atau terakhir mengubah keputusan. Kosong jika dibuat oleh kunci API."
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          },
          "inherited_from": {
            "type": "object",
            "nullable": true,
            "description": "Brand yang keputusannya diikuti oleh entitas ini karena Anda tidak membuat keputusan pada entitas itu sendiri. Null jika keputusan tersebut merupakan milik pihak lawan itu sendiri.",
            "properties": {
              "id": {
                "type": "string",
                "format": "uuid"
              },
              "name": {
                "type": "string"
              }
            }
          }
        }
      },
      "TravelRuleCounterpartyDecisionResponse": {
        "type": "object",
        "properties": {
          "decision": {
            "allOf": [
              {
                "$ref": "#/components/schemas/TravelRuleCounterpartyDecision"
              }
            ],
            "nullable": true,
            "description": "Keputusan yang berlaku untuk pihak lawan bagi aplikasi Anda: miliknya sendiri, atau jika tidak (untuk entitas dari sebuah merek) milik merek tersebut. Null jika tidak ada."
          }
        }
      },
      "TravelRuleCounterpartyDecisionRequest": {
        "type": "object",
        "required": [
          "decision"
        ],
        "properties": {
          "decision": {
            "type": "string",
            "enum": [
              "APPROVED",
              "RESTRICTED",
              "BLOCKED"
            ]
          },
          "reason": {
            "type": "string",
            "maxLength": 255,
            "description": "Opsional. Menggantikan alasan sebelumnya; jangan sertakan untuk menghapusnya."
          }
        }
      },
      "TravelRuleCounterpartyScreening": {
        "type": "object",
        "description": "Satu skrining sanksi dan media negatif dari entitas pihak lawan, dijalankan untuk dan ditagihkan ke aplikasi Anda. Bersifat privat untuk aplikasi Anda: pelanggan lain tidak akan pernah melihatnya.",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "status": {
            "type": "string",
            "enum": [
              "Approved",
              "In Review",
              "Declined"
            ],
            "description": "Disetujui: tidak ada kecocokan potensial yang memerlukan perhatian. Dalam Peninjauan atau Ditolak: potensi kecocokan sanksi atau media negatif."
          },
          "total_hits": {
            "type": "integer",
            "description": "Berapa banyak kemungkinan kecocokan yang dikembalikan oleh skrining."
          },
          "score": {
            "type": "number",
            "nullable": true,
            "description": "Skor risiko tertinggi di antara kemungkinan kecocokan. Null jika tidak ada yang cocok."
          },
          "screened_at": {
            "type": "string",
            "format": "date-time"
          },
          "fresh": {
            "type": "boolean",
            "description": "Apakah usia skrining kurang dari fresh_days (30 hari). Skrining baru akan digunakan kembali alih-alih ditagih lagi."
          },
          "flagged": {
            "type": "boolean",
            "description": "true selama skrining masih baru dan statusnya Dalam Peninjauan atau Ditolak. Selama skrining terbaru Anda ditandai dan skrining pihak lawan tetap aktif, counterparty_risk_level bernilai HIGH dalam aturan Anda."
          }
        }
      },
      "TravelRuleCounterpartyScreeningStatus": {
        "type": "object",
        "properties": {
          "enabled": {
            "type": "boolean",
            "description": "Pengaturan Travel Rule counterparty_screening_enabled Anda. Nonaktif secara default; tidak ada skrining atau penagihan selama pengaturan ini nonaktif."
          },
          "price": {
            "type": "string",
            "description": "String desimal, dalam USD: biaya satu skrining untuk organisasi Anda, harga Skrining AML Perusahaan."
          },
          "fresh_days": {
            "type": "integer",
            "description": "Berapa hari suatu skrining tetap dianggap baru dan digunakan kembali."
          },
          "screening": {
            "allOf": [
              {
                "$ref": "#/components/schemas/TravelRuleCounterpartyScreening"
              }
            ],
            "nullable": true,
            "description": "Skrining terbaru Anda terhadap pihak lawan. Null jika Anda belum pernah melakukan skrining terhadapnya."
          }
        }
      },
      "TravelRuleCounterpartyScreeningRequest": {
        "type": "object",
        "properties": {
          "refresh": {
            "type": "boolean",
            "default": false,
            "description": "true melakukan skrining lagi (dan menagih lagi) bahkan ketika skrining terkini sudah ada."
          }
        }
      },
      "TravelRuleCounterpartyScreeningResult": {
        "type": "object",
        "properties": {
          "outcome": {
            "type": "string",
            "enum": [
              "screened",
              "reused"
            ],
            "description": "screened: skrining baru dijalankan dan ditagih (201). reused: skrining terkini dikembalikan dan tidak ada yang ditagih (200)."
          },
          "screening": {
            "$ref": "#/components/schemas/TravelRuleCounterpartyScreening"
          }
        }
      },
      "TravelRuleCounterpartyQuestionnaire": {
        "type": "object",
        "description": "Satu kuesioner uji tuntas (due-diligence) yang dikirim aplikasi Anda ke pihak lawan: kuesioner standar Didit, dikirimkan melalui email ke alamat kepatuhan yang tercatat dengan tautan jawaban sekali pakai. Bersifat privat bagi aplikasi Anda.",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "status": {
            "type": "string",
            "enum": [
              "SENT",
              "ANSWERED",
              "EXPIRED"
            ],
            "description": "SENT: menunggu jawaban. ANSWERED: pihak lawan menjawab setiap pertanyaan. EXPIRED: tautan jawaban ditutup tanpa dijawab (batas waktunya terlampaui, atau kuesioner baru menggantikannya), atau jawaban telah melewati valid_until."
          },
          "form_version": {
            "type": "string",
            "description": "Versi kuesioner standar Didit tempat jawaban tersebut berada. Saat ini 1."
          },
          "sent_to": {
            "type": "string",
            "format": "email"
          },
          "sent_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "expires_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Batas waktu untuk menjawab, 30 hari setelah pengiriman. Tautan berhenti berfungsi setelah batas waktu tersebut."
          },
          "answered_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "valid_until": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Berapa lama jawaban tetap berlaku: 365 hari setelah dijawab. Null hingga dijawab."
          },
          "current": {
            "type": "boolean",
            "description": "true selama kuesioner bernilai ANSWERED dan valid_until belum lewat."
          },
          "answers": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            },
            "description": "Jawaban yang dipetakan berdasarkan ID pertanyaan: legal_name, licensing, jurisdictions, aml_program, compliance_officer, sanctions_screening, transaction_monitoring, travel_rule, custody, ownership, record_keeping, data_protection. Setiap jawaban hingga 2.000 karakter. Kosong hingga dijawab."
          }
        }
      },
      "TravelRuleCounterpartyQuestionnaireRequest": {
        "type": "object",
        "properties": {
          "sent_to": {
            "type": "string",
            "format": "email",
            "description": "Opsional. Alamat kepatuhan yang tercatat untuk pihak lawan: untuk entri direktori berupa alamat kepatuhannya atau kontak yang dilihat aplikasi Anda, untuk anggota jaringan Didit berupa email kepatuhannya yang telah dikonfirmasi. Default: alamat tujuan pengiriman email Travel Rule ke pihak lawan (kontak Anda sendiri terlebih dahulu, lalu kontak platform, kemudian alamat kepatuhan entri)."
          }
        }
      },
      "TravelRuleCounterpartyQuestionnaireList": {
        "type": "object",
        "properties": {
          "questionnaires": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TravelRuleCounterpartyQuestionnaire"
            },
            "description": "Terbaru terlebih dahulu."
          }
        }
      },
      "TravelRulePickupInfo": {
        "type": "object",
        "description": "Pertukaran tertunda di balik tautan penjemputan yang dikirim melalui email, sebagaimana ditampilkan pada halaman respons pihak lawan.",
        "properties": {
          "reference": {
            "type": "string",
            "format": "uuid",
            "description": "uuid transfer, seperti yang ditampilkan konsol VASP pengirim."
          },
          "requested_at": {
            "type": "string",
            "format": "date-time"
          },
          "originator_vasp_name": {
            "type": "string"
          },
          "originator_vasp_lei": {
            "type": "string"
          },
          "recipient_vasp_name": {
            "type": "string",
            "description": "VASP pihak lawan yang menjadi tujuan permintaan."
          },
          "language": {
            "type": "string",
            "description": "Bahasa email permintaan dan halaman respons, dari yurisdiksi pihak lawan."
          },
          "amount": {
            "type": "string"
          },
          "currency": {
            "type": "string"
          },
          "fiat_amount": {
            "type": "string",
            "description": "Nilai terkonversi yang diberikan pengirim, atau kosong."
          },
          "fiat_currency": {
            "type": "string"
          },
          "chain": {
            "type": "string"
          },
          "beneficiary_wallet": {
            "type": "string"
          },
          "status": {
            "type": "string"
          },
          "ivms_version": {
            "type": "string"
          },
          "deadline_at": {
            "type": "string",
            "format": "date-time",
            "description": "Waktu tautan berhenti merespons."
          },
          "reminders_sent": {
            "type": "integer"
          },
          "contact": {
            "type": "string",
            "description": "Nilai `?contact=` dari tautan, ditampilkan kembali; kosong jika tautan tidak memilikinya."
          },
          "decline_reasons": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "data_mismatch",
                "not_our_customer",
                "wallet_not_hosted",
                "sanctions",
                "risk_appetite",
                "jurisdiction",
                "insufficient_data",
                "other"
              ]
            },
            "description": "Nilai yang diterima `decline_reason`."
          },
          "join_invitation": {
            "type": "object",
            "description": "Apakah pihak lawan memiliki undangan aktif untuk bergabung dengan Didit secara gratis. Tautan undangan hanya dikirim melalui email ke alamat yang diundang, sehingga `url` kosong di sini.",
            "properties": {
              "eligible": {
                "type": "boolean"
              },
              "url": {
                "type": "string"
              }
            }
          },
          "originator_data": {
            "type": "object",
            "description": "Kolom pengirim yang dibagikan oleh VASP pengirim (`data_sharing_fields`). Nama dan dompet selalu disertakan."
          },
          "beneficiary_data": {
            "type": "object"
          },
          "ivms_request": {
            "type": "object",
            "description": "Permintaan yang sama sebagai objek IVMS 101. Ditiadakan saat `data_masked` bernilai true."
          },
          "data_masked": {
            "type": "boolean",
            "description": "Selalu false pada endpoint ini: permintaan email bersifat keluar (outbound), dan pengguna milik pengirim tidak pernah disamarkan."
          }
        }
      },
      "TravelRulePickupRespondRequest": {
        "type": "object",
        "required": [
          "decision"
        ],
        "properties": {
          "decision": {
            "type": "string",
            "enum": [
              "accept",
              "decline"
            ]
          },
          "beneficiary_name": {
            "type": "string",
            "description": "Nama penerima sebagaimana tercatat dalam data Anda, diproses melalui aturan nama VASP pengirim. `ivms_response` diutamakan jika mencantumkan penerima.",
            "maxLength": 255
          },
          "decline_reason": {
            "type": "string",
            "enum": [
              "",
              "data_mismatch",
              "not_our_customer",
              "wallet_not_hosted",
              "sanctions",
              "risk_appetite",
              "jurisdiction",
              "insufficient_data",
              "other"
            ],
            "description": "Alasan mengapa Anda menolak. Dicatat pada linimasa transfer VASP pengirim. Kosong (default) jika Anda tidak memberikan alasan."
          },
          "decline_detail": {
            "type": "string",
            "maxLength": 512,
            "description": "Teks bebas; wajib diisi jika `decision` adalah `decline` dan `decline_reason` adalah `other`."
          },
          "ivms_response": {
            "type": "object",
            "description": "Respons IVMS 101 lengkap Anda. Nama penerimanya diprioritaskan atas `beneficiary_name`."
          },
          "contact": {
            "type": "string",
            "format": "uuid",
            "description": "Kontak tujuan pengiriman tautan, dari nilai `?contact=` pada tautan. Jika body tidak menyertakannya, parameter kueri `contact` yang digunakan."
          }
        }
      },
      "TravelRuleInboundRequest": {
        "type": "object",
        "required": [
          "chain",
          "txid",
          "wallet_address",
          "amount",
          "currency"
        ],
        "properties": {
          "chain": {
            "type": "string",
            "description": "Chain tempat deposit diselesaikan, misalnya `ETH`. Disimpan dalam huruf kecil dan dibandingkan secara tidak peka huruf besar/kecil dengan entri buku alamat dompet Anda, jadi gunakan token chain yang sama di sana.",
            "maxLength": 32
          },
          "txid": {
            "type": "string",
            "description": "Hash transaksi on-chain. Dideduplikasi bersama dengan wallet_address.",
            "maxLength": 128
          },
          "wallet_address": {
            "type": "string",
            "description": "Dompet tujuan tempat Anda menerima setoran. X-address XRP dipisahkan menjadi alamat klasik dan tag-nya.",
            "maxLength": 128
          },
          "amount": {
            "type": "string",
            "description": "Jumlah deposit sebagai string desimal, nol atau lebih besar, hingga 18 tempat desimal."
          },
          "currency": {
            "type": "string",
            "description": "Aset deposit, misalnya \"USDC\".",
            "maxLength": 16
          },
          "originator_data": {
            "type": "object",
            "description": "Detail pengirim dari VASP pengirim, jika diketahui, sebagai objek datar seperti `{\"name\": \"...\"}`. Didit membaca name (atau full_name), first_name, last_name, dan vendor_data darinya.",
            "additionalProperties": true
          },
          "beneficiary_data": {
            "type": "object",
            "description": "Detail penerima (pelanggan Anda), sebagai objek datar seperti `{\"name\": \"...\"}`. Didit mencocokkan name dengan holder_name dari entri buku alamat yang cocok, dan menyetel wallet_address serta chain dari permintaan.",
            "additionalProperties": true
          },
          "originating_vasp": {
            "type": "object",
            "description": "Deskripsi opsional dari VASP pengirim. Deskripsi ini hanya berada pada transfer ini (`metadata.originating_vasp`, dan VASP pengirim transfer di GET /v3/travel-rule/transfers/); tidak pernah membuat, mengedit, atau menautkan entri direktori VASP bersama.",
            "properties": {
              "name": {
                "type": "string",
                "maxLength": 255
              },
              "lei": {
                "type": "string",
                "maxLength": 20,
                "description": "Opsional. LEI ISO 17442 20 karakter yang valid, atau kosong."
              },
              "travel_address": {
                "type": "string",
                "description": "Travel Address pengirim, dicatat pada transfer ini.",
                "maxLength": 512
              }
            }
          },
          "memo": {
            "type": "string",
            "maxLength": 256,
            "description": "Opsional. Tag tujuan deposit atau memo pada jaringan memo: pada alamat deposit bersama, nilai ini membedakan pelanggan Anda, dan entri buku alamat untuk memo tersebut dicocokkan. XRP: tag tujuan, bilangan bulat dari 0 hingga 4294967295 (angka JSON diterima). XLM: memo teks hingga 28 byte, ID 64-bit, atau hash heksadesimal 32 byte. EOS: hingga 256 byte. ATOM: hingga 256 karakter. HBAR: hingga 100 byte. Dompet Bitcoin, EVM, Solana, Tron, Litecoin, Bitcoin Cash, Dogecoin, dan Lightning tidak menerima memo: adanya memo menghasilkan `400`. Alias: `destinationTag` atau `destination_tag`."
          },
          "utxo": {
            "allOf": [
              {
                "$ref": "#/components/schemas/TravelRuleUtxo"
              }
            ],
            "description": "Opsional, hanya rantai UTXO. Input dan output transaksi deposit: dompet pengirim adalah `originator_data.wallet_address` yang dideklarasikan, jika tidak, input terbesar."
          }
        }
      },
      "TravelRuleInboundResponse": {
        "type": "object",
        "properties": {
          "transaction_id": {
            "type": "string",
            "format": "uuid",
            "description": "UUID transaksi Didit untuk deposit masuk."
          },
          "txn_id": {
            "type": "string",
            "description": "txn_id transaksi masuk: dibuat oleh Didit saat Didit membuat transaksi, atau milik Anda sendiri saat deposit yang belum diklaim digunakan kembali."
          },
          "created": {
            "type": "boolean",
            "description": "true saat panggilan ini mendaftarkan transfer (HTTP 201); false saat transfer untuk txid dan wallet_address yang sama sudah ada (HTTP 200)."
          },
          "travel_rule": {
            "$ref": "#/components/schemas/TravelRuleTransferDetail"
          }
        }
      },
      "TravelRuleTestVaspInboundRequest": {
        "type": "object",
        "required": [
          "beneficiary_wallet_address"
        ],
        "properties": {
          "beneficiary_wallet_address": {
            "type": "string",
            "description": "Alamat dompet tujuan. Didit Test VASP mengirimkan ke alamat tersebut, dicocokkan dengan buku alamat dompet Anda pada rantai aset tersebut. Dompet tanpa entri yang cocok tetap diterima dan transaksi masuk dicatat ON_HOLD."
          },
          "scenario": {
            "type": "string",
            "enum": [
              "accept",
              "name_mismatch"
            ],
            "default": "accept",
            "description": "Pernyataan Didit Test VASP mengenai siapa penerimanya. `accept` menyatakan nama pemilik sendiri; `name_mismatch` menyatakan nama yang tidak disetujui oleh pemilik mana pun. Keputusan itu sendiri selalu menjadi milik Anda."
          },
          "chain": {
            "type": "string",
            "default": "ETH",
            "description": "Chain dari aset."
          },
          "amount": {
            "type": "string",
            "default": "1",
            "description": "Jumlah sebagai string desimal."
          },
          "currency": {
            "type": "string",
            "default": "ETH",
            "description": "Kode aset."
          },
          "reference": {
            "type": "string",
            "description": "Kunci idempotensi opsional. Pengulangan dengan nilai yang sama mengembalikan transfer yang telah dibukukan oleh panggilan pertama."
          }
        }
      },
      "TravelRuleTestVaspInboundResponse": {
        "type": "object",
        "properties": {
          "transaction_id": {
            "type": "string",
            "format": "uuid",
            "description": "UUID transaksi Didit dari transfer masuk."
          },
          "txn_id": {
            "type": "string",
            "description": "txn_id yang dibuat oleh Didit."
          },
          "scenario": {
            "type": "string",
            "description": "Skenario yang dijalankan."
          },
          "travel_rule_status": {
            "type": "string",
            "description": "Status yang dihasilkan dari keputusan aplikasi Anda sendiri."
          },
          "detail": {
            "type": "string",
            "description": "Alasan mengapa transfer berakhir dengan status tersebut."
          },
          "test_vasp": {
            "type": "boolean",
            "description": "Selalu true: pengirimnya adalah Didit Test VASP."
          },
          "travel_rule": {
            "$ref": "#/components/schemas/TravelRuleTransferDetail"
          }
        }
      },
      "TravelRuleWidgetSessionCreate": {
        "type": "object",
        "properties": {
          "wallet_address": {
            "type": "string",
            "description": "Alamat dompet yang akan diverifikasi. Opsional; jika kosong, alamat harus diberikan saat proses pembuktian dimulai.",
            "maxLength": 128
          },
          "chain": {
            "type": "string",
            "description": "Token chain untuk alamat, misalnya `ETH`, `BTC`, atau `SOL`. Gunakan token yang sama seperti di buku alamat dompet Anda. Penandatanganan pesan dan pengujian Satoshi hanya ditawarkan untuk chain yang didukung. Entri buku alamat yang diverifikasi oleh bukti menyimpannya di bawah pengidentifikasi kanonisnya (ETH, BTC, SOL, TRX).",
            "maxLength": 32
          },
          "holder_name": {
            "type": "string",
            "description": "Nama pemegang dompet, digunakan untuk pencocokan nama penerima.",
            "maxLength": 255
          },
          "vendor_data": {
            "type": "string",
            "description": "Pengenal internal Anda untuk pemegang, diteruskan ke entri buku alamat yang dibuat.",
            "maxLength": 255
          },
          "transaction_id": {
            "type": "string",
            "format": "uuid",
            "description": "Opsional. UUID transaksi Didit dari transfer Travel Rule yang akan dilanjutkan saat bukti terverifikasi.",
            "nullable": true
          },
          "satoshi_deposit_address": {
            "type": "string",
            "description": "Opsional. Alamat deposit yang Anda kendalikan; menyediakannya akan mengaktifkan metode pembuktian SATOSHI_TEST.",
            "maxLength": 128
          },
          "callback_url": {
            "type": "string",
            "description": "Opsional. URL http(s) absolut tempat widget mengembalikan pelanggan setelah selesai.",
            "maxLength": 512
          },
          "expires_in_minutes": {
            "type": "integer",
            "description": "Opsional. Masa berlaku tautan yang dibuat, dalam hitungan menit. Diperpanjang secara otomatis untuk mencakup jendela uji Satoshi saat SATOSHI_TEST ditawarkan.",
            "default": 60,
            "minimum": 5,
            "maximum": 10080
          }
        }
      },
      "TravelRuleWidgetSessionResponse": {
        "type": "object",
        "properties": {
          "widget_session_id": {
            "type": "string",
            "format": "uuid"
          },
          "token": {
            "type": "string",
            "description": "Token sesi opaque yang disematkan dalam URL widget."
          },
          "url": {
            "type": "string",
            "description": "URL widget kepemilikan dompet yang di-hosting. Buka secara persis di browser sistem (jangan pernah di dalam webview SDK seluler)."
          },
          "expires_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "TravelRuleWidgetContext": {
        "type": "object",
        "properties": {
          "vasp_name": {
            "type": "string",
            "description": "Nama resmi dari profil VASP Anda, yang ditampilkan kepada pelanggan di widget. Kosong jika tidak ada profil."
          },
          "wallet_address": {
            "type": "string"
          },
          "chain": {
            "type": "string",
            "description": "Rantai tempat sesi diterbitkan, sesuai yang Anda kirimkan."
          },
          "chain_family": {
            "type": "string",
            "nullable": true,
            "enum": [
              "EVM",
              "BTC",
              "SOL",
              "TRON",
              null
            ],
            "description": "Keluarga kunci di balik rantai: EVM (Ethereum, BNB Chain, Polygon, Arbitrum, Base, Optimism, Avalanche, Linea, dan rantai EVM lainnya), BTC, SOL, atau TRON. Satu kunci EVM mengontrol alamat yang sama di setiap rantai EVM. Bernilai null jika tidak ada tanda tangan yang dapat diverifikasi pada rantai tersebut."
          },
          "holder_name": {
            "type": "string"
          },
          "allowed_methods": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "MESSAGE_SIGNING",
                "SCREENSHOT",
                "SATOSHI_TEST",
                "SELF_DECLARATION"
              ]
            },
            "description": "Metode bukti yang tersedia untuk sesi ini. MESSAGE_SIGNING memerlukan chain dengan chain_family, SATOSHI_TEST memerlukan satoshi_deposit_address pada sesi dan chain yang setorannya dapat dibaca kembali oleh Didit, SCREENSHOT memerlukan pengaturan allow_screenshot_proof, dan SELF_DECLARATION memerlukan pengaturan allow_self_declaration."
          },
          "transfer_status": {
            "type": "string",
            "nullable": true,
            "description": "Status transfer Travel Rule yang ditautkan. Null jika sesi dibuat tanpa transaction_id."
          },
          "callback_url": {
            "type": "string",
            "description": "Tujuan widget mengarahkan pelanggan kembali setelah selesai. Kosong jika tidak diatur."
          },
          "expires_at": {
            "type": "string",
            "format": "date-time"
          },
          "completed_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Bernilai non-null setelah bukti diverifikasi."
          },
          "proofs": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TravelRuleWidgetProofSummary"
            }
          },
          "max_attempts": {
            "type": "integer",
            "description": "Bukti dompet yang ditolak yang diizinkan oleh sesi ini."
          },
          "attempts_used": {
            "type": "integer",
            "description": "Bukti yang ditolak sejauh ini."
          },
          "attempts_remaining": {
            "type": "integer",
            "description": "Jika bernilai 0, memulai bukti lain akan merespons dengan 409 dan Anda membuat sesi widget baru."
          },
          "customization": {
            "type": "object",
            "nullable": true,
            "description": "Kustomisasi White Label aplikasi (warna, logo, keluarga font) saat White Label diaktifkan - widget ditampilkan dengan branding yang sama seperti alur verifikasi. Bernilai null jika tidak."
          }
        }
      },
      "TravelRuleWidgetProofSummary": {
        "type": "object",
        "properties": {
          "proof_id": {
            "type": "string",
            "format": "uuid"
          },
          "method": {
            "type": "string",
            "enum": [
              "MESSAGE_SIGNING",
              "SATOSHI_TEST",
              "SCREENSHOT",
              "SELF_DECLARATION"
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "PENDING",
              "VERIFIED",
              "REJECTED",
              "EXPIRED"
            ],
            "description": "PENDING: pengguna akhir memilih metode ini dan bukti belum diputuskan. Tanda tangan yang gagal atau deposit uji yang belum dapat dibaca atau belum dikonfirmasi membuat bukti tetap PENDING dengan failure_reason, sehingga pengguna akhir dapat mencoba lagi; deposit SATOSHI_TEST yang dikirimkan diperiksa ulang secara otomatis hingga jendelanya ditutup, dan SCREENSHOT yang dikirimkan menunggu peninjauan Anda. VERIFIED: kepemilikan terbukti. REJECTED: deposit uji benar-benar salah (pengirim lain, bukan jumlah yang diharapkan ke alamat deposit, lebih lama dari tantangan, atau transaksi yang sudah membuktikan dompet lain) atau peninjau Anda menolak tangkapan layar; failure_reason menyatakan alasannya. Bukti yang ditolak bersifat final dan menggunakan salah satu upaya sesi. EXPIRED: bukti tidak dapat lagi diputuskan (jendelanya ditutup, pengguna akhir berganti metode, sesi widget berakhir, atau pemegang dompet berubah); failure_reason menyatakan alasannya."
          },
          "wallet_address": {
            "type": "string"
          },
          "chain": {
            "type": "string",
            "description": "Pengenal blockchain kanonis untuk entri buku alamat tempat bukti tersebut ditujukan, misalnya ETH, BTC, SOL, TRX."
          },
          "deposit_address": {
            "type": "string",
            "nullable": true,
            "description": "Alamat deposit yang harus dikirimi jumlah Satoshi untuk pengujian oleh pelanggan. Hanya ada pada bukti SATOSHI_TEST."
          },
          "expected_amount": {
            "type": "string",
            "nullable": true,
            "description": "Jumlah on-chain persis, dalam mata uang asli deposit, yang harus cocok dengan deposit uji coba Satoshi. Hanya ada pada bukti SATOSHI_TEST."
          },
          "expires_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Batas waktu untuk jendela Satoshi test milik bukti ini. Hanya ada pada bukti SATOSHI_TEST; expires_at milik sesi widget diperpanjang untuk mencakupnya saat SATOSHI_TEST ditawarkan."
          },
          "challenge": {
            "type": "string",
            "nullable": true,
            "description": "Pesan yang diterbitkan Didit yang ditandatangani pelanggan dengan dompet mereka. Hanya ada pada bukti MESSAGE_SIGNING."
          },
          "rejection_reason": {
            "type": "string",
            "description": "Alasan mengapa bukti ditolak, sebagai kalimat bahasa Inggris untuk pengguna akhir. Hanya ada jika `status` adalah REJECTED; kosong saat peninjau Anda menolak tangkapan layar (catatan Anda tetap tersimpan untuk Anda)."
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "attempts": {
            "type": "integer",
            "description": "Berapa kali bukti diserahkan untuk bukti ini (tanda tangan, id transaksi, unggahan)."
          },
          "failure_reason": {
            "allOf": [
              {
                "$ref": "#/components/schemas/TravelRuleWalletProofFailureReason"
              }
            ],
            "description": "Alasan mengapa upaya terakhir gagal, atau mengapa bukti ditutup. Kosong jika tidak ada yang gagal."
          }
        }
      },
      "CaseSubject": {
        "type": "object",
        "nullable": true,
        "description": "Satu pengguna atau bisnis tempat kasus diikat.",
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "user",
              "business"
            ]
          },
          "uuid": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "external_id": {
            "type": "string",
            "nullable": true,
            "description": "vendor_data subjek."
          },
          "country": {
            "type": "string",
            "nullable": true,
            "description": "Kode negara tiga huruf dari subjek (ISO 3166-1 alpha-3), atau null jika tidak diketahui. Untuk bisnis, berupa negara pendiriannya. Untuk perorangan, berupa negara penerbit dokumen identitas dari verifikasi mereka; perorangan dengan dokumen dari beberapa negara akan menampilkan salah satunya, dan kode dokumen ICAO seperti `XXA` dapat muncul.",
            "example": "ESP"
          },
          "portrait": {
            "type": "string",
            "format": "uri",
            "nullable": true,
            "description": "URL bertanda tangan berdurasi singkat dari gambar potret individu tersebut. Selalu null untuk bisnis, dan null untuk individu tanpa potret. URL ini kedaluwarsa, jadi unduh gambar tersebut saat Anda membaca kasus alih-alih menyimpan URL-nya."
          }
        }
      },
      "CaseAssignee": {
        "type": "object",
        "nullable": true,
        "properties": {
          "uuid": {
            "type": "string",
            "format": "uuid"
          },
          "full_name": {
            "type": "string"
          },
          "email": {
            "type": "string",
            "format": "email"
          }
        }
      },
      "CaseBlueprintSummary": {
        "type": "object",
        "nullable": true,
        "properties": {
          "uuid": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string",
            "maxLength": 24
          }
        }
      },
      "CaseContentConfig": {
        "type": "object",
        "description": "Enam bagian yang dapat diaktifkan/dinonaktifkan yang menentukan tab dan kolom mana yang muncul di halaman kasus. Bagian atau kunci yang tidak dikenal akan ditolak.",
        "properties": {
          "checklist": {
            "type": "object",
            "properties": {
              "enabled": {
                "type": "boolean"
              },
              "optional": {
                "type": "boolean",
                "description": "Jika true, kasus dapat diselesaikan dengan item daftar periksa yang belum lengkap."
              },
              "items": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "label": {
                      "type": "string",
                      "maxLength": 255
                    },
                    "order": {
                      "type": "integer"
                    }
                  }
                }
              }
            }
          },
          "aml_control": {
            "type": "object",
            "properties": {
              "enabled": {
                "type": "boolean"
              },
              "financial": {
                "type": "boolean"
              },
              "identity": {
                "type": "boolean"
              }
            }
          },
          "identity": {
            "type": "object",
            "properties": {
              "enabled": {
                "type": "boolean"
              },
              "personal_information": {
                "type": "boolean"
              },
              "applicant_tags": {
                "type": "boolean"
              },
              "contact_information": {
                "type": "boolean"
              },
              "risk_overview": {
                "type": "boolean"
              },
              "poi_documents": {
                "type": "boolean"
              },
              "poa_documents": {
                "type": "boolean"
              }
            }
          },
          "verifications": {
            "type": "object",
            "properties": {
              "enabled": {
                "type": "boolean"
              },
              "summary": {
                "type": "boolean"
              }
            }
          },
          "reporting": {
            "type": "object",
            "properties": {
              "enabled": {
                "type": "boolean"
              },
              "fiu_reports": {
                "type": "boolean"
              }
            }
          },
          "financial": {
            "type": "object",
            "properties": {
              "enabled": {
                "type": "boolean"
              },
              "payment_methods": {
                "type": "boolean"
              },
              "transactions": {
                "type": "boolean"
              }
            }
          }
        }
      },
      "CaseNote": {
        "type": "object",
        "properties": {
          "uuid": {
            "type": "string",
            "format": "uuid"
          },
          "comment": {
            "type": "string"
          },
          "actor_email": {
            "type": "string",
            "format": "email",
            "nullable": true
          },
          "actor_name": {
            "type": "string",
            "nullable": true
          },
          "mentioned_emails": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "email"
            }
          },
          "is_internal": {
            "type": "boolean"
          },
          "attachments": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "s3_key": {
                  "type": "string"
                },
                "filename": {
                  "type": "string"
                },
                "file_size": {
                  "type": "integer"
                },
                "url": {
                  "type": "string",
                  "format": "uri"
                }
              }
            }
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "CaseEvent": {
        "type": "object",
        "properties": {
          "uuid": {
            "type": "string",
            "format": "uuid"
          },
          "event_type": {
            "type": "string",
            "enum": [
              "CREATED",
              "STATUS_CHANGED",
              "ASSIGNED",
              "UNASSIGNED",
              "RESOLVED",
              "REOPENED",
              "LINK_ADDED",
              "LINK_REMOVED",
              "NOTE_ADDED",
              "NOTE_PINNED",
              "NOTE_UNPINNED",
              "PRIORITY_CHANGED",
              "DUE_DATE_CHANGED",
              "TAG_ADDED",
              "TAG_REMOVED",
              "ESCALATED",
              "TRANSFERRED",
              "CHECKLIST_COMPLETED",
              "REPORT_CREATED",
              "REPORT_FINALIZED",
              "SUBMITTED_FOR_APPROVAL",
              "APPROVAL_GRANTED",
              "APPROVAL_REJECTED",
              "ENTITY_ACTION",
              "APPROVAL_INVALIDATED",
              "CUSTOMER_REQUEST",
              "STAGE_CHANGED",
              "TEAM_CHANGED",
              "CHECKER_ASSIGNED",
              "CHECKER_UNASSIGNED"
            ]
          },
          "actor_email": {
            "type": "string",
            "format": "email",
            "nullable": true
          },
          "actor_name": {
            "type": "string",
            "nullable": true
          },
          "previous_status": {
            "type": "string",
            "enum": [
              "OPEN",
              "AWAITING_USER",
              "RESOLVED"
            ],
            "nullable": true
          },
          "new_status": {
            "type": "string",
            "enum": [
              "OPEN",
              "AWAITING_USER",
              "RESOLVED"
            ],
            "nullable": true
          },
          "metadata": {
            "type": "object"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "CaseLink": {
        "type": "object",
        "properties": {
          "uuid": {
            "type": "string",
            "format": "uuid"
          },
          "linked_entity_type": {
            "type": "string",
            "enum": [
              "session",
              "business_session",
              "transaction"
            ],
            "nullable": true
          },
          "linked_entity_uuid": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "linked_entity_summary": {
            "type": "object",
            "nullable": true,
            "description": "session_id/session_number/status untuk tautan session dan business_session; uuid/txn_id/status untuk tautan transaction."
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "CaseChecklistItem": {
        "type": "object",
        "properties": {
          "uuid": {
            "type": "string",
            "format": "uuid"
          },
          "label": {
            "type": "string",
            "maxLength": 255
          },
          "is_completed": {
            "type": "boolean"
          },
          "completed_by": {
            "type": "string",
            "format": "email",
            "nullable": true
          },
          "completed_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "order": {
            "type": "integer"
          }
        }
      },
      "CaseBlueprintListItem": {
        "type": "object",
        "properties": {
          "uuid": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string",
            "maxLength": 24
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "assignment_method": {
            "type": "string",
            "enum": [
              "MANUAL",
              "AUTOMATIC"
            ]
          },
          "assignee_pool": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "uuid"
            }
          },
          "max_active_cases": {
            "type": "integer",
            "nullable": true
          },
          "escalation_enabled": {
            "type": "boolean"
          },
          "transfer_enabled": {
            "type": "boolean"
          },
          "require_resolution_note": {
            "type": "boolean"
          },
          "is_active": {
            "type": "boolean"
          },
          "preset_key": {
            "type": "string",
            "nullable": true
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "version": {
            "type": "integer",
            "readOnly": true
          },
          "default_deadline_hours": {
            "type": "integer",
            "nullable": true,
            "minimum": 1,
            "maximum": 8760
          }
        }
      },
      "CaseBlueprintDetail": {
        "type": "object",
        "properties": {
          "uuid": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string",
            "maxLength": 24
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "assignment_method": {
            "type": "string",
            "enum": [
              "MANUAL",
              "AUTOMATIC"
            ]
          },
          "assignee_pool": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "uuid"
            }
          },
          "max_active_cases": {
            "type": "integer",
            "nullable": true
          },
          "escalation_enabled": {
            "type": "boolean"
          },
          "transfer_enabled": {
            "type": "boolean"
          },
          "require_resolution_note": {
            "type": "boolean"
          },
          "is_active": {
            "type": "boolean"
          },
          "preset_key": {
            "type": "string",
            "nullable": true
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "escalation_blueprint": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "escalation_blueprint_name": {
            "type": "string",
            "nullable": true
          },
          "four_eyes_checker_blueprint": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "four_eyes_checker_blueprint_name": {
            "type": "string",
            "nullable": true
          },
          "content_config": {
            "type": "object",
            "description": "Enam bagian yang dapat diaktifkan/dinonaktifkan yang menentukan tab dan kolom mana yang muncul di halaman kasus. Bagian atau kunci yang tidak dikenal akan ditolak.",
            "properties": {
              "checklist": {
                "type": "object",
                "properties": {
                  "enabled": {
                    "type": "boolean"
                  },
                  "optional": {
                    "type": "boolean",
                    "description": "Jika true, kasus dapat diselesaikan dengan item daftar periksa yang belum lengkap."
                  },
                  "items": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "label": {
                          "type": "string",
                          "maxLength": 255
                        },
                        "order": {
                          "type": "integer"
                        }
                      }
                    }
                  }
                }
              },
              "aml_control": {
                "type": "object",
                "properties": {
                  "enabled": {
                    "type": "boolean"
                  },
                  "financial": {
                    "type": "boolean"
                  },
                  "identity": {
                    "type": "boolean"
                  }
                }
              },
              "identity": {
                "type": "object",
                "properties": {
                  "enabled": {
                    "type": "boolean"
                  },
                  "personal_information": {
                    "type": "boolean"
                  },
                  "applicant_tags": {
                    "type": "boolean"
                  },
                  "contact_information": {
                    "type": "boolean"
                  },
                  "risk_overview": {
                    "type": "boolean"
                  },
                  "poi_documents": {
                    "type": "boolean"
                  },
                  "poa_documents": {
                    "type": "boolean"
                  }
                }
              },
              "verifications": {
                "type": "object",
                "properties": {
                  "enabled": {
                    "type": "boolean"
                  },
                  "summary": {
                    "type": "boolean"
                  }
                }
              },
              "reporting": {
                "type": "object",
                "properties": {
                  "enabled": {
                    "type": "boolean"
                  },
                  "fiu_reports": {
                    "type": "boolean"
                  }
                }
              },
              "financial": {
                "type": "object",
                "properties": {
                  "enabled": {
                    "type": "boolean"
                  },
                  "payment_methods": {
                    "type": "boolean"
                  },
                  "transactions": {
                    "type": "boolean"
                  }
                }
              }
            }
          },
          "creation_sources": {
            "type": "array",
            "description": "Konektor yang saat ini merutekan kasus baru ke dalam cetak biru ini.",
            "items": {
              "type": "object",
              "properties": {
                "kind": {
                  "type": "string",
                  "enum": [
                    "aml",
                    "rule",
                    "workflow"
                  ]
                },
                "id": {
                  "type": "string"
                },
                "name": {
                  "type": "string"
                }
              }
            }
          },
          "receives_escalation_from": {
            "type": "array",
            "description": "Blueprint lain yang target Eskalasinya mengarah ke blueprint ini.",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "name": {
                  "type": "string"
                }
              }
            }
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          },
          "version": {
            "type": "integer",
            "readOnly": true
          },
          "default_deadline_hours": {
            "type": "integer",
            "nullable": true,
            "minimum": 1,
            "maximum": 8760
          }
        }
      },
      "CaseListItem": {
        "type": "object",
        "properties": {
          "uuid": {
            "type": "string",
            "format": "uuid"
          },
          "case_number": {
            "type": "string",
            "nullable": true,
            "description": "Ditetapkan secara otomatis, contoh CS-0001."
          },
          "title": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "OPEN",
              "AWAITING_USER",
              "RESOLVED"
            ]
          },
          "resolution": {
            "type": "string",
            "enum": [
              "FALSE_POSITIVE",
              "VALID_THREAT",
              "INCONCLUSIVE",
              "REQUIREMENTS_NOT_MET",
              "REQUIREMENTS_SATISFIED"
            ],
            "nullable": true
          },
          "pending_resolution": {
            "type": "object",
            "nullable": true,
            "description": "Ditetapkan hanya saat resolusi 4-eyes disiapkan pada cetak biru checker, menunggu persetujuan atau penolakan persetujuan.",
            "properties": {
              "resolution": {
                "type": "string",
                "enum": [
                  "FALSE_POSITIVE",
                  "VALID_THREAT",
                  "INCONCLUSIVE",
                  "REQUIREMENTS_NOT_MET",
                  "REQUIREMENTS_SATISFIED"
                ]
              },
              "resolution_notes": {
                "type": "string",
                "nullable": true
              },
              "maker_email": {
                "type": "string",
                "format": "email",
                "nullable": true,
                "description": "Email petugas yang mengirimkan resolusi. Null jika dikirimkan dengan kunci API: resolusi tersebut tidak memiliki pembuat yang tercatat, sehingga approve dan reject-approval mengembalikan 403 untuk setiap pemanggil."
              },
              "maker_name": {
                "type": "string",
                "nullable": true
              },
              "maker_user_id": {
                "type": "string",
                "format": "uuid",
                "nullable": true,
                "description": "UUID pengguna anggota dari petugas yang mengirimkan penyelesaian. Null jika kunci API yang mengirimkannya. Anggota tersebut tidak dapat disebutkan sebagai `checker`."
              },
              "maker_blueprint_id": {
                "type": "string",
                "format": "uuid"
              },
              "staged_at": {
                "type": "string",
                "format": "date-time"
              }
            }
          },
          "checker": {
            "$ref": "#/components/schemas/CaseChecker"
          },
          "priority": {
            "type": "string",
            "enum": [
              "LOW",
              "MEDIUM",
              "HIGH"
            ]
          },
          "source": {
            "type": "string",
            "enum": [
              "MANUAL",
              "AML_SCREENING",
              "TRANSACTION_RULE",
              "WORKFLOW_BUILDER"
            ]
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "subject": {
            "$ref": "#/components/schemas/CaseSubject"
          },
          "assigned_to": {
            "$ref": "#/components/schemas/CaseAssignee"
          },
          "assigned_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "team": {
            "$ref": "#/components/schemas/CaseTeamSummary"
          },
          "due_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "resolved_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "created_by_email": {
            "type": "string",
            "nullable": true
          },
          "created_by_name": {
            "type": "string",
            "nullable": true
          },
          "blueprint": {
            "$ref": "#/components/schemas/CaseBlueprintSummary"
          },
          "links_count": {
            "type": "integer"
          },
          "notes_count": {
            "type": "integer"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          },
          "application_id": {
            "type": "string",
            "format": "uuid"
          },
          "application_name": {
            "type": "string"
          },
          "organization_id": {
            "type": "string",
            "format": "uuid"
          },
          "organization_name": {
            "type": "string"
          }
        }
      },
      "CaseDetail": {
        "type": "object",
        "properties": {
          "uuid": {
            "type": "string",
            "format": "uuid"
          },
          "case_number": {
            "type": "string",
            "nullable": true
          },
          "title": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "OPEN",
              "AWAITING_USER",
              "RESOLVED"
            ]
          },
          "resolution": {
            "type": "string",
            "enum": [
              "FALSE_POSITIVE",
              "VALID_THREAT",
              "INCONCLUSIVE",
              "REQUIREMENTS_NOT_MET",
              "REQUIREMENTS_SATISFIED"
            ],
            "nullable": true
          },
          "resolution_notes": {
            "type": "string",
            "nullable": true
          },
          "priority": {
            "type": "string",
            "enum": [
              "LOW",
              "MEDIUM",
              "HIGH"
            ]
          },
          "source": {
            "type": "string",
            "enum": [
              "MANUAL",
              "AML_SCREENING",
              "TRANSACTION_RULE",
              "WORKFLOW_BUILDER"
            ]
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "subject": {
            "$ref": "#/components/schemas/CaseSubject"
          },
          "assigned_to": {
            "$ref": "#/components/schemas/CaseAssignee"
          },
          "assigned_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "team": {
            "$ref": "#/components/schemas/CaseTeamSummary"
          },
          "due_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "resolved_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "resolved_by_email": {
            "type": "string",
            "nullable": true
          },
          "pending_resolution": {
            "type": "object",
            "nullable": true,
            "description": "Ditetapkan hanya saat resolusi 4-eyes disiapkan pada cetak biru checker, menunggu persetujuan atau penolakan persetujuan.",
            "properties": {
              "resolution": {
                "type": "string",
                "enum": [
                  "FALSE_POSITIVE",
                  "VALID_THREAT",
                  "INCONCLUSIVE",
                  "REQUIREMENTS_NOT_MET",
                  "REQUIREMENTS_SATISFIED"
                ]
              },
              "resolution_notes": {
                "type": "string",
                "nullable": true
              },
              "maker_email": {
                "type": "string",
                "format": "email",
                "nullable": true,
                "description": "Email petugas yang mengirimkan resolusi. Null jika dikirimkan dengan kunci API: resolusi tersebut tidak memiliki pembuat yang tercatat, sehingga approve dan reject-approval mengembalikan 403 untuk setiap pemanggil."
              },
              "maker_name": {
                "type": "string",
                "nullable": true
              },
              "maker_user_id": {
                "type": "string",
                "format": "uuid",
                "nullable": true,
                "description": "UUID pengguna anggota dari petugas yang mengirimkan penyelesaian. Null jika kunci API yang mengirimkannya. Anggota tersebut tidak dapat disebutkan sebagai `checker`."
              },
              "maker_blueprint_id": {
                "type": "string",
                "format": "uuid"
              },
              "staged_at": {
                "type": "string",
                "format": "date-time"
              }
            }
          },
          "checker": {
            "$ref": "#/components/schemas/CaseChecker"
          },
          "metadata": {
            "type": "object"
          },
          "blueprint": {
            "$ref": "#/components/schemas/CaseBlueprintDetail"
          },
          "notes": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CaseNote"
            },
            "description": "50 catatan terbaru."
          },
          "events": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CaseEvent"
            },
            "description": "100 event terbaru."
          },
          "links": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CaseLink"
            }
          },
          "links_count": {
            "type": "integer"
          },
          "notes_count": {
            "type": "integer"
          },
          "checklist_items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CaseChecklistItem"
            }
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "ReportTemplateDetail": {
        "type": "object",
        "properties": {
          "uuid": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "jurisdiction": {
            "type": "string",
            "minLength": 2,
            "maxLength": 2,
            "description": "Kode negara ISO 3166-1 alpha-2."
          },
          "report_type": {
            "type": "string",
            "enum": [
              "SAR",
              "STR",
              "CTR",
              "TTR",
              "UTR",
              "IFT",
              "CBR",
              "TFR"
            ]
          },
          "report_type_display": {
            "type": "string"
          },
          "field_config": {
            "type": "object",
            "description": "Nilai default header goAML yang dapat digunakan kembali. Kolom wajib tingkat templat: rentity_id, submission_code, dan currency_code_local (3 huruf). Opsional: enabled_fields (blok laporan opsional mana yang disertakan) ditambah nilai default reporting_person, location, reason, dan action. Kolom header per pengajuan (action, submission_date, transactions, jurisdiction) diberlakukan saat laporan divalidasi atau difinalisasi, bukan pada templat."
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "RegulatoryReportDetail": {
        "type": "object",
        "properties": {
          "uuid": {
            "type": "string",
            "format": "uuid"
          },
          "case_uuid": {
            "type": "string",
            "format": "uuid"
          },
          "case_number": {
            "type": "string",
            "nullable": true
          },
          "report_type": {
            "type": "string",
            "enum": [
              "SAR",
              "STR",
              "CTR",
              "TTR",
              "UTR",
              "IFT",
              "CBR",
              "TFR"
            ]
          },
          "report_type_display": {
            "type": "string"
          },
          "report_code": {
            "type": "string",
            "description": "kode laporan goAML yang diturunkan dari report_type, misalnya STR, CTR, BCR."
          },
          "report_number": {
            "type": "string",
            "nullable": true
          },
          "status": {
            "type": "string",
            "enum": [
              "DRAFT",
              "VALIDATED",
              "FINALIZED"
            ]
          },
          "status_display": {
            "type": "string"
          },
          "jurisdiction": {
            "type": "string",
            "minLength": 2,
            "maxLength": 2
          },
          "rentity_id": {
            "type": "string",
            "nullable": true,
            "description": "ID entitas pelapor yang diterbitkan oleh FIU."
          },
          "rentity_branch": {
            "type": "string",
            "nullable": true
          },
          "submission_code": {
            "type": "string",
            "enum": [
              "E",
              "M"
            ]
          },
          "entity_reference": {
            "type": "string",
            "nullable": true
          },
          "fiu_ref_number": {
            "type": "string",
            "nullable": true
          },
          "currency_code_local": {
            "type": "string",
            "minLength": 3,
            "maxLength": 3,
            "nullable": true
          },
          "submission_date": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "reporting_person": {
            "type": "object"
          },
          "location": {
            "type": "object"
          },
          "reason": {
            "type": "string",
            "nullable": true
          },
          "action": {
            "type": "string",
            "nullable": true
          },
          "activity": {
            "type": "string",
            "nullable": true
          },
          "narrative": {
            "type": "object",
            "description": "Bagian narasi 5W.",
            "properties": {
              "who": {
                "type": "string"
              },
              "what": {
                "type": "string"
              },
              "when": {
                "type": "string"
              },
              "where": {
                "type": "string"
              },
              "why": {
                "type": "string"
              },
              "how": {
                "type": "string"
              }
            }
          },
          "report_indicators": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "included_fields": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "transactions": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "uuid"
            }
          },
          "validation_errors": {
            "type": "array",
            "description": "Hasil validasi terbaru; setiap entri berupa objek {field, message}.",
            "items": {
              "type": "object",
              "properties": {
                "field": {
                  "type": "string"
                },
                "message": {
                  "type": "string"
                }
              }
            }
          },
          "validated_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "finalized_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "created_by_email": {
            "type": "string",
            "nullable": true
          },
          "created_by_name": {
            "type": "string",
            "nullable": true
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "TransactionRuleCondition": {
        "type": "object",
        "required": [
          "field",
          "operator"
        ],
        "properties": {
          "field": {
            "type": "string",
            "description": "Jalur kolom transaksi yang akan dievaluasi. Kolom inti: amount, currency, direction, action_type, score, severity, transaction_type, payment_details, preferred_currency_amount (beralih ke amount_in_default_currency jika tidak tersedia), default_currency_code, subject_country, counterparty_country, subject_vendor_data, counterparty_vendor_data, subject_device_fingerprint, counterparty_device_fingerprint, subject_browser_family, subject_browser_version, subject_platform, subject_accept_language, subject_session_age_ms, subject_ip_country, counterparty_ip_country, subject_ip_address, counterparty_ip_address, subject_payment_method_type, subject_payment_method_country, subject_payment_method_fingerprint, subject_payment_method_account_id (dan padanan counterparty_payment_method_*), travel_rule_status, travel_rule_required, travel_rule_obligations_count, counterparty_dd_status (keputusan Anda tentang pihak lawan Travel Rule: APPROVED, RESTRICTED, atau BLOCKED, suatu entitas yang mengikuti keputusan mereknya), counterparty_risk_level (LOW, MEDIUM, atau HIGH; HIGH saat skrining pihak lawan Anda sendiri ditandai), counterparty_jurisdiction (negara VASP pihak lawan), counterparty_responsiveness (RESPONSIVE, UNRESPONSIVE, atau UNKNOWN), subject_days_since_previous_transaction, tags, dan custom_values.<key> untuk kunci apa pun yang dikirimkan dalam custom_properties saat pembuatan transaksi. Kolom kode negara menerima ISO-2 atau ISO-3; kedua sisi dinormalisasi ke ISO-3 sebelum dibandingkan."
          },
          "operator": {
            "type": "string",
            "enum": [
              "eq",
              "ne",
              "gt",
              "gte",
              "lt",
              "lte",
              "in",
              "not_in",
              "contains",
              "not_contains",
              "contains_any",
              "regex",
              "fuzzy_match",
              "exists",
              "is_not_empty",
              "is_not_null",
              "not_exists",
              "is_empty",
              "is_null"
            ],
            "description": "Operator perbandingan. in/not_in menguji keanggotaan (nilai dapat berupa daftar atau skalar tunggal). contains/not_contains adalah pemeriksaan substring tanpa membedakan huruf besar/kecil terhadap nilai string. contains_any menerima daftar string dan cocok jika salah satunya merupakan substring tanpa membedakan huruf besar/kecil dari nilai kolom. regex mencocokkan pola nilai terhadap kolom. fuzzy_match membandingkan terhadap string nilai dengan ambang batas `score` yang diperlukan (0-100). gt/gte/lt/lte tidak pernah cocok jika salah satu sisi tidak ada. exists/is_not_empty/is_not_null (alias) dan not_exists/is_empty/is_null (alias) adalah pemeriksaan keberadaan yang mengabaikan `value`."
          },
          "value": {
            "description": "Nilai perbandingan. Bentuknya bergantung pada operator dan value_type; jangan sertakan untuk operator pemeriksaan keberadaan. Setiap operator lainnya memerlukan nilai yang bukan `null` atau daftar kosong, jika tidak, aturan akan ditolak dengan `400`. `contains_any` memerlukan daftar string, dan `contains`, `not_contains`, serta `regex` memerlukan string tunggal."
          },
          "value_type": {
            "type": "string",
            "enum": [
              "list",
              "field",
              "relative_date"
            ],
            "description": "Interpretasi nilai opsional. `list`: nilai adalah UUID Daftar dan entri daftar menjadi nilai perbandingan. `field`: nilai adalah jalur kolom lain, dibandingkan antarkolom. `relative_date`: nilai adalah objek tanggal relatif, mis. {\"direction\": \"past\", \"unit\": \"days\", \"amount\": 30}."
          },
          "score": {
            "type": "number",
            "minimum": 0,
            "maximum": 100,
            "description": "Wajib jika operator adalah fuzzy_match: ambang batas kemiripan 0-100."
          },
          "group_index": {
            "type": "integer",
            "description": "Logika terkelompok opsional. Ketika kondisi apa pun membawa group_index, kondisi yang berbagi indeks membentuk sebuah grup dan evaluasi terkelompok menggantikan evaluation_mode."
          },
          "group_logic": {
            "type": "string",
            "enum": [
              "AND",
              "OR"
            ],
            "default": "AND",
            "description": "Cara kondisi digabungkan DI DALAM grup."
          },
          "groups_logic": {
            "type": "string",
            "enum": [
              "AND",
              "OR"
            ],
            "default": "OR",
            "description": "Cara hasil grup digabungkan DI SELURUH grup. Dibaca dari kondisi pertama."
          }
        },
        "description": "Kondisi hanya membaca transaksi yang sedang dievaluasi - kondisi ini tidak pernah memfilter jendela agregasi."
      },
      "TransactionRuleAggregation": {
        "type": "object",
        "required": [
          "value"
        ],
        "properties": {
          "metric": {
            "type": "string",
            "enum": [
              "count",
              "sum",
              "max",
              "min",
              "avg",
              "distinct_count"
            ],
            "default": "count",
            "description": "Bagaimana transaksi historis yang cocok diagregasikan. unique_count diterima sebagai alias dari distinct_count."
          },
          "field": {
            "type": "string",
            "default": "amount",
            "description": "Kolom yang diagregasikan berdasarkan sum/max/min/avg/distinct_count. Diabaikan untuk count."
          },
          "operator": {
            "type": "string",
            "enum": [
              "eq",
              "ne",
              "gt",
              "gte",
              "lt",
              "lte"
            ],
            "default": "eq",
            "description": "Perbandingan yang diterapkan pada metrik yang dihitung."
          },
          "value": {
            "type": "number",
            "description": "Ambang batas yang dibandingkan dengan metrik terhitung."
          },
          "window": {
            "type": "string",
            "pattern": "^\\d+(m|h|d)$",
            "default": "1d",
            "description": "Periode penelusuran mundur yang berakhir pada txn_date transaksi: <N>m (MENIT, bukan bulan), <N>h (jam), atau <N>d (hari), misalnya 30m, 24h, 7d, 30d."
          },
          "filters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Mempersempit transaksi historis mana yang diagregasi. Kunci berupa jalur kolom dari katalog kolom kondisi; nilai \"__current__\" diselesaikan ke nilai kolom yang sama pada transaksi yang sedang dievaluasi (misalnya {\"subject_vendor_data\": \"__current__\"} membatasi rentang waktu pada subjek yang sama), dan nilai daftar berarti keanggotaan. Catatan tanpa nilai yang dikelompokkan tidak akan pernah dikelompokkan bersama: ketika transaksi yang dievaluasi tidak memiliki nilai untuk kolom \"__current__\" (tidak ada pihak lawan, tidak ada sidik jari perangkat), agregasi tidak cocok, apa pun operatornya. Filter HANYA membandingkan berdasarkan kesetaraan atau keanggotaan - tidak ada filter lt/gte, sehingga rentang seperti \"transaksi historis di bawah 10.000\" tidak dapat dinyatakan di sini. Tempatkan rentang pada metrik sebagai gantinya (metrik max dengan operator lt mempertahankan setiap transaksi di dalam rentang waktu di bawah ambang batas)."
          }
        },
        "description": "Pemeriksaan kecepatan (velocity check) terhadap riwayat transaksi aplikasi di dalam jendela waktu. Setiap entri agregasi harus cocok agar aturan cocok, terlepas dari evaluation_mode. Agregasi hanya membatasi jendela waktu; transaksi yang sedang dievaluasi dibatasi oleh cakupan dan kondisi, jadi ulangi direction, currency, atau transaction_type di kedua bagian saat aturan memerlukannya."
      },
      "TransactionRuleScope": {
        "type": "object",
        "properties": {
          "transaction_types": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Batasi ke jenis transaksi, mis. finance, kyc, travel_rule, user_event. Kosong atau tidak ada = tanpa pembatasan."
          },
          "directions": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "INBOUND",
                "OUTBOUND"
              ]
            },
            "description": "Batasi ke arah transaksi (tidak peka huruf besar/kecil saat penulisan)."
          },
          "action_types": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Batasi ke nilai action_type Anda, mis. withdrawal, deposit."
          }
        },
        "description": "Transaksi mana yang dikenai aturan ini. Hanya ketiga kunci ini yang diterima."
      },
      "TransactionRuleAction": {
        "oneOf": [
          {
            "$ref": "#/components/schemas/TransactionRuleActionAddScore"
          },
          {
            "$ref": "#/components/schemas/TransactionRuleActionChangeStatus"
          },
          {
            "$ref": "#/components/schemas/TransactionRuleActionAddTags"
          },
          {
            "$ref": "#/components/schemas/TransactionRuleActionAddNote"
          },
          {
            "$ref": "#/components/schemas/TransactionRuleActionAddToList"
          },
          {
            "$ref": "#/components/schemas/TransactionRuleActionOpenCase"
          }
        ],
        "discriminator": {
          "propertyName": "type",
          "mapping": {
            "add_score": "#/components/schemas/TransactionRuleActionAddScore",
            "change_status": "#/components/schemas/TransactionRuleActionChangeStatus",
            "add_tags": "#/components/schemas/TransactionRuleActionAddTags",
            "add_note": "#/components/schemas/TransactionRuleActionAddNote",
            "add_to_list": "#/components/schemas/TransactionRuleActionAddToList",
            "open_case": "#/components/schemas/TransactionRuleActionOpenCase"
          }
        },
        "description": "Satu tindakan aturan. Suatu aturan dapat memuat beberapa tindakan; semuanya diterapkan bersamaan saat cocok. Aturan dalam mode TEST mencatat apa yang seharusnya dilakukan tanpa menerapkan tindakan apa pun."
      },
      "TransactionRuleCreateRequest": {
        "type": "object",
        "required": [
          "title",
          "category",
          "mode"
        ],
        "properties": {
          "title": {
            "type": "string",
            "description": "Nama aturan. Unik per aplikasi di antara aturan yang tidak dihapus; duplikat menghasilkan 400."
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "category": {
            "type": "string",
            "description": "Tema risiko yang digunakan untuk pengelompokan dan pelaporan, mis. finance, aml_ctf, anomaly_detection, fatf, device_intelligence, crypto_monitoring, travel_rule, responsible_gaming, e_commerce."
          },
          "mode": {
            "type": "string",
            "enum": [
              "ACTIVE",
              "DISABLED",
              "TEST"
            ],
            "description": "ACTIVE mengevaluasi secara langsung. TEST mengevaluasi dan mencatat eksekusi aturan tetapi tidak pernah memengaruhi skor atau status - mode awal yang disarankan. DISABLED dilewati."
          },
          "evaluation_mode": {
            "type": "string",
            "enum": [
              "ALL",
              "ANY"
            ],
            "default": "ALL",
            "description": "Menentukan apakah setiap kondisi harus cocok (ALL) atau setidaknya satu (ANY). Diabaikan jika kondisi menggunakan group_index."
          },
          "scope": {
            "$ref": "#/components/schemas/TransactionRuleScope"
          },
          "conditions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TransactionRuleCondition"
            }
          },
          "aggregation": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TransactionRuleAggregation"
            }
          },
          "actions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TransactionRuleAction"
            }
          },
          "metadata": {
            "type": "object",
            "description": "Metadata bentuk bebas yang disimpan pada aturan."
          }
        },
        "description": "Membuat aturan CUSTOM. Aturan dalam mode ACTIVE langsung berlaku untuk transaksi baru - buat dalam mode TEST dan lakukan backtest terlebih dahulu."
      },
      "TransactionRuleUpdateRequest": {
        "type": "object",
        "properties": {
          "title": {
            "type": "string",
            "description": "Nama aturan. Unik per aplikasi di antara aturan yang tidak dihapus; duplikat menghasilkan 400."
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "category": {
            "type": "string",
            "description": "Tema risiko yang digunakan untuk pengelompokan dan pelaporan, mis. finance, aml_ctf, anomaly_detection, fatf, device_intelligence, crypto_monitoring, travel_rule, responsible_gaming, e_commerce."
          },
          "mode": {
            "type": "string",
            "enum": [
              "ACTIVE",
              "DISABLED",
              "TEST"
            ],
            "description": "ACTIVE mengevaluasi secara langsung. TEST mengevaluasi dan mencatat eksekusi aturan tetapi tidak pernah memengaruhi skor atau status - mode awal yang disarankan. DISABLED dilewati."
          },
          "evaluation_mode": {
            "type": "string",
            "enum": [
              "ALL",
              "ANY"
            ],
            "default": "ALL",
            "description": "Menentukan apakah setiap kondisi harus cocok (ALL) atau setidaknya satu (ANY). Diabaikan jika kondisi menggunakan group_index."
          },
          "scope": {
            "$ref": "#/components/schemas/TransactionRuleScope"
          },
          "conditions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TransactionRuleCondition"
            }
          },
          "aggregation": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TransactionRuleAggregation"
            }
          },
          "actions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TransactionRuleAction"
            }
          },
          "metadata": {
            "type": "object",
            "description": "Metadata bentuk bebas yang disimpan pada aturan."
          }
        },
        "description": "Pembaruan parsial. Aturan kustom menerima semua kolom; aturan pustaka (PRESET) hanya menerima mode - hal lain akan mengembalikan 400."
      },
      "TransactionRuleDetail": {
        "type": "object",
        "properties": {
          "uuid": {
            "type": "string",
            "format": "uuid"
          },
          "title": {
            "type": "string",
            "description": "Nama aturan. Unik per aplikasi di antara aturan yang tidak dihapus; duplikat menghasilkan 400."
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "category": {
            "type": "string",
            "description": "Tema risiko yang digunakan untuk pengelompokan dan pelaporan, mis. finance, aml_ctf, anomaly_detection, fatf, device_intelligence, crypto_monitoring, travel_rule, responsible_gaming, e_commerce."
          },
          "mode": {
            "type": "string",
            "enum": [
              "ACTIVE",
              "DISABLED",
              "TEST"
            ],
            "description": "ACTIVE mengevaluasi secara langsung. TEST mengevaluasi dan mencatat eksekusi aturan tetapi tidak pernah memengaruhi skor atau status - mode awal yang disarankan. DISABLED dilewati."
          },
          "evaluation_mode": {
            "type": "string",
            "enum": [
              "ALL",
              "ANY"
            ],
            "default": "ALL",
            "description": "Menentukan apakah setiap kondisi harus cocok (ALL) atau setidaknya satu (ANY). Diabaikan jika kondisi menggunakan group_index."
          },
          "scope": {
            "$ref": "#/components/schemas/TransactionRuleScope"
          },
          "conditions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TransactionRuleCondition"
            }
          },
          "aggregation": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TransactionRuleAggregation"
            }
          },
          "actions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TransactionRuleAction"
            }
          },
          "metadata": {
            "type": "object",
            "description": "Metadata bentuk bebas yang disimpan pada aturan."
          },
          "severity": {
            "type": "string",
            "enum": [
              "UNKNOWN",
              "LOW",
              "MEDIUM",
              "HIGH",
              "CRITICAL"
            ],
            "nullable": true,
            "description": "Tingkat keparahan informasional yang dibawa oleh aturan pustaka; tidak dapat diatur pada aturan kustom."
          },
          "source": {
            "type": "string",
            "enum": [
              "PRESET",
              "CUSTOM"
            ],
            "description": "Aturan PRESET berasal dari pustaka (instalasi/pencopotan, pengeditan khusus mode); aturan CUSTOM sepenuhnya milik Anda."
          },
          "library_key": {
            "type": "string",
            "nullable": true,
            "description": "Pengidentifikasi pustaka yang stabil; null untuk aturan kustom."
          },
          "latest_triggered_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "run_count": {
            "type": "integer",
            "description": "Berapa banyak transaksi yang cocok dengan aturan ini."
          },
          "approved_count": {
            "type": "integer"
          },
          "reviewed_count": {
            "type": "integer"
          },
          "declined_count": {
            "type": "integer"
          },
          "awaiting_user_count": {
            "type": "integer"
          },
          "approved_pct": {
            "type": "number"
          },
          "reviewed_pct": {
            "type": "number"
          },
          "declined_pct": {
            "type": "number"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "TransactionRuleBacktestRequest": {
        "type": "object",
        "properties": {
          "conditions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TransactionRuleCondition"
            },
            "default": []
          },
          "aggregation": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TransactionRuleAggregation"
            },
            "default": []
          },
          "evaluation_mode": {
            "type": "string",
            "enum": [
              "ALL",
              "ANY"
            ],
            "default": "ALL"
          },
          "scope": {
            "$ref": "#/components/schemas/TransactionRuleScope"
          },
          "period_days": {
            "type": "integer",
            "minimum": 1,
            "maximum": 365,
            "default": 90
          }
        },
        "description": "Konfigurasi aturan hipotetis untuk dievaluasi terhadap transaksi terkini. Bersifat hanya-baca dan gratis: tidak ada yang dibuat atau dimodifikasi. Kirim conditions, aggregation, evaluation_mode, DAN scope yang sama seperti aturan yang ingin Anda aktifkan. Conditions, aggregation, dan scope yang dihilangkan tidak menambahkan batasan tersendiri; menghapus scope dapat menyertakan arah atau jenis transaksi yang dilewati oleh aturan yang disimpan. evaluation_mode yang dihilangkan secara default bernilai ALL (yang dapat mengurangi kecocokan untuk aturan ANY), dan period_days yang dihilangkan secara default bernilai 90 hari, bukan riwayat tanpa batas."
      },
      "TransactionRuleBacktestResult": {
        "type": "object",
        "properties": {
          "evaluated": {
            "type": "integer",
            "description": "Transaksi yang dievaluasi (terbaru lebih dulu, dibatasi)."
          },
          "matched": {
            "type": "integer",
            "description": "Transaksi yang akan sesuai dengan konfigurasi tersebut."
          },
          "affected_entities": {
            "type": "integer",
            "description": "Subjek unik (berdasarkan vendor_data) di antara hasil yang cocok."
          },
          "period_days": {
            "type": "integer"
          }
        }
      },
      "TransactionRuleLibraryEntry": {
        "type": "object",
        "properties": {
          "library_key": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "category": {
            "type": "string"
          },
          "evaluation_mode": {
            "type": "string",
            "enum": [
              "ALL",
              "ANY"
            ]
          },
          "scope": {
            "$ref": "#/components/schemas/TransactionRuleScope"
          },
          "conditions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TransactionRuleCondition"
            }
          },
          "aggregation": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TransactionRuleAggregation"
            }
          },
          "actions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TransactionRuleAction"
            }
          },
          "metadata": {
            "type": "object"
          },
          "bundle": {
            "type": "string",
            "nullable": true,
            "description": "Kategori fungsional, mis. finance, aml_ctf, crypto_monitoring, travel_rule, responsible_gaming."
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "industries": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "source": {
            "type": "string"
          },
          "is_installed": {
            "type": "boolean",
            "description": "Apakah preset ini saat ini terpasang pada aplikasi."
          }
        }
      },
      "TransactionRuleInstallRequest": {
        "type": "object",
        "properties": {
          "library_keys": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Preset spesifik untuk diinstal atau dihapus instalasinya."
          },
          "bundle": {
            "type": "string",
            "description": "Sebagai gantinya, instal atau hapus instalasi setiap preset dalam bundel ini."
          }
        },
        "description": "Sediakan library_keys ATAU bundle."
      },
      "TransactionRuleInstallResult": {
        "type": "object",
        "properties": {
          "installed_library_keys": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Hanya POST (instalasi): preset yang diinstal oleh panggilan ini."
          },
          "installed_count": {
            "type": "integer",
            "description": "Hanya POST (instalasi)."
          },
          "uninstalled_count": {
            "type": "integer",
            "description": "DELETE (uninstal) saja: preset yang dihapus oleh panggilan ini."
          }
        }
      },
      "WalletScreeningResult": {
        "type": "object",
        "properties": {
          "provider": {
            "type": "string",
            "description": "Penyedia yang melakukan skrining (misalnya `merklescience`, `crystal`)."
          },
          "screening_type": {
            "type": "string",
            "enum": [
              "WALLET_SCREENING"
            ],
            "description": "Selalu `WALLET_SCREENING` untuk endpoint ini."
          },
          "risk_score": {
            "type": "integer",
            "description": "Skor risiko 0-100 yang dinormalisasi. Nilai lebih tinggi berarti paparan lebih besar terhadap entitas berisiko. Merkle Science menilai alamat 0-5, yang dipetakan ke 0, 15, 35, 55, 75, atau 95."
          },
          "severity": {
            "type": "string",
            "enum": [
              "UNKNOWN",
              "LOW",
              "MEDIUM",
              "HIGH",
              "CRITICAL"
            ],
            "description": "Kelompok risiko diturunkan dari `risk_score`: `0-9` UNKNOWN, `10-39` LOW, `40-69` MEDIUM, `70-89` HIGH, `90-100` CRITICAL. `UNKNOWN` adalah rentang terendah, bukan status tanpa data yang terpisah: `risk_score` 0 (kasus alamat bersih yang umum) berarti tidak ada penilaian buruk, sedangkan skor bukan nol dalam rentang 1-9 adalah sinyal nyata tetapi di bawah LOW - baca `risk_score`, bukan hanya kelompoknya. Jangan pernah memperlakukan `UNKNOWN` sebagai indikasi afirmatif bahwa risikonya rendah atau penilaian bersih; jangan menampilkannya sebagai lolos."
          },
          "status": {
            "type": "string",
            "enum": [
              "SCREENED",
              "PENDING",
              "ERROR"
            ],
            "description": "Status hasil skrining."
          },
          "summary": {
            "type": "string",
            "description": "Ringkasan hasil skrining yang dapat dibaca manusia."
          },
          "wallet_address": {
            "type": "string",
            "description": "Alamat yang diskrining, dikembalikan apa adanya."
          },
          "transaction_hash": {
            "type": "string",
            "nullable": true,
            "description": "Kolom skrining transaksi, digunakan bersama struktur hasil. Selalu `null` pada hasil skrining dompet."
          },
          "blockchain": {
            "type": "string",
            "description": "Blockchain yang diskrining."
          },
          "block_timestamp": {
            "type": "string",
            "nullable": true,
            "description": "Kolom skrining transaksi, digunakan bersama struktur hasil. Selalu `null` pada hasil skrining dompet."
          },
          "total_value_usd": {
            "type": "number",
            "nullable": true,
            "description": "Kolom skrining transaksi, digunakan bersama struktur hasil. Selalu `null` pada hasil skrining dompet."
          },
          "fee_usd": {
            "type": "number",
            "nullable": true,
            "description": "Kolom skrining transaksi, digunakan bersama struktur hasil. Selalu `null` pada hasil skrining dompet."
          },
          "sender_rows": {
            "type": "array",
            "items": {
              "type": "object"
            },
            "description": "Kolom skrining transaksi, digunakan bersama struktur hasil. Selalu kosong pada hasil skrining dompet."
          },
          "receiver_rows": {
            "type": "array",
            "items": {
              "type": "object"
            },
            "description": "Kolom skrining transaksi, digunakan bersama struktur hasil. Selalu kosong pada hasil skrining dompet."
          },
          "transaction_flows": {
            "type": "array",
            "items": {
              "type": "object"
            },
            "description": "Kolom skrining transaksi, digunakan bersama struktur hasil. Selalu kosong pada hasil skrining dompet."
          },
          "transaction_flows_status": {
            "type": "string",
            "nullable": true,
            "description": "Kolom skrining transaksi, digunakan bersama struktur hasil. Selalu `null` pada hasil skrining dompet."
          },
          "transaction_flows_error": {
            "type": "string",
            "nullable": true,
            "description": "Kolom skrining transaksi, digunakan bersama struktur hasil. Selalu `null` pada hasil skrining dompet."
          },
          "source_of_funds": {
            "type": "array",
            "description": "Dari mana alamat tersebut menerima dana, diatribusikan berdasarkan entitas. Setiap entri merupakan rincian eksposur.",
            "items": {
              "type": "object",
              "properties": {
                "category": {
                  "type": "string",
                  "description": "Kategori risiko yang dinormalisasi, misalnya `exchange_licensed`, `dex`, `defi`, `payment_processor`, `mixer`, `darknet_market`, `sanctioned`, `stolen_funds`, `high_risk_exchange`."
                },
                "percentage": {
                  "type": "number",
                  "description": "Porsi total paparan arah tersebut, 0-100."
                },
                "amount_usd": {
                  "type": "number",
                  "nullable": true,
                  "description": "Nilai USD yang diatribusikan ke entitas ini."
                },
                "entity_name": {
                  "type": "string",
                  "nullable": true,
                  "description": "Nama entitas yang diatribusikan, misalnya bursa, mixer, atau kelompok yang terkena sanksi."
                },
                "entity_type": {
                  "type": "string",
                  "nullable": true,
                  "description": "Tipe entitas penyedia (misalnya `Exchange`, `DeFi`, `Sanctions`, `Theft`)."
                },
                "entity_subtype": {
                  "type": "string",
                  "nullable": true,
                  "description": "Subtipe yang lebih terperinci (misalnya `Mandatory KYC and AML`, `OFAC`, `Yield Aggregator`)."
                },
                "hops": {
                  "type": "integer",
                  "nullable": true,
                  "description": "Jumlah hop ke entitas (1 untuk pihak lawan langsung), jika penyedia melaporkannya. Selalu `null` untuk Merkle Science, yang hanya melaporkan apakah eksposur bersifat langsung atau tidak langsung: gunakan `exposure_type`."
                },
                "description": {
                  "type": "string",
                  "nullable": true,
                  "description": "`entity_type / entity_subtype`, sebagaimana penyedia memberi label pada entitas."
                },
                "is_direct": {
                  "type": "boolean",
                  "description": "True saat `exposure_type` bernilai `direct`."
                },
                "exposure_direction": {
                  "type": "string",
                  "enum": [
                    "incoming",
                    "outgoing",
                    "connected"
                  ],
                  "description": "Apakah dana berasal dari (`incoming`) atau dikirim ke (`outgoing`) entitas ini."
                },
                "exposure_type": {
                  "type": "string",
                  "enum": [
                    "direct",
                    "indirect"
                  ],
                  "description": "Eksposur `direct` (1 lompatan) atau `indirect` (multi-lompatan)."
                },
                "provider_entity_id": {
                  "type": "string",
                  "nullable": true,
                  "description": "Pengenal milik penyedia sendiri untuk entitas tersebut."
                },
                "provider_entity_type_id": {
                  "type": "string",
                  "nullable": true,
                  "description": "Pengenal milik penyedia sendiri untuk `entity_type`."
                },
                "provider_entity_subtype_id": {
                  "type": "string",
                  "nullable": true,
                  "description": "Pengenal milik penyedia sendiri untuk `entity_subtype`."
                },
                "country": {
                  "type": "string",
                  "nullable": true,
                  "description": "Negara utama entitas berdasarkan ISO 3166-1 alpha-2. Kosong atau `null` ketika penyedia tidak mengetahuinya."
                },
                "raw_amount": {
                  "type": "number",
                  "nullable": true,
                  "description": "Jumlah dalam unit aset itu sendiri, saat penyedia melaporkannya."
                },
                "raw_currency": {
                  "type": "string",
                  "nullable": true,
                  "description": "Satuan dari `raw_amount`, saat penyedia melaporkannya."
                }
              }
            }
          },
          "destination_of_funds": {
            "type": "array",
            "description": "Ke mana alamat tersebut mengirim dana, diatribusikan berdasarkan entitas. Bentuk item sama seperti `source_of_funds` dengan `exposure_direction` = `outgoing`.",
            "items": {
              "type": "object",
              "properties": {
                "category": {
                  "type": "string",
                  "description": "Kategori risiko yang dinormalisasi, misalnya `exchange_licensed`, `dex`, `defi`, `payment_processor`, `mixer`, `darknet_market`, `sanctioned`, `stolen_funds`, `high_risk_exchange`."
                },
                "percentage": {
                  "type": "number",
                  "description": "Porsi total paparan arah tersebut, 0-100."
                },
                "amount_usd": {
                  "type": "number",
                  "nullable": true,
                  "description": "Nilai USD yang diatribusikan ke entitas ini."
                },
                "entity_name": {
                  "type": "string",
                  "nullable": true,
                  "description": "Nama entitas yang diatribusikan, misalnya bursa, mixer, atau kelompok yang terkena sanksi."
                },
                "entity_type": {
                  "type": "string",
                  "nullable": true,
                  "description": "Tipe entitas penyedia (misalnya `Exchange`, `DeFi`, `Sanctions`, `Theft`)."
                },
                "entity_subtype": {
                  "type": "string",
                  "nullable": true,
                  "description": "Subtipe yang lebih terperinci (misalnya `Mandatory KYC and AML`, `OFAC`, `Yield Aggregator`)."
                },
                "hops": {
                  "type": "integer",
                  "nullable": true,
                  "description": "Jumlah hop ke entitas (1 untuk pihak lawan langsung), jika penyedia melaporkannya. Selalu `null` untuk Merkle Science, yang hanya melaporkan apakah eksposur bersifat langsung atau tidak langsung: gunakan `exposure_type`."
                },
                "description": {
                  "type": "string",
                  "nullable": true,
                  "description": "`entity_type / entity_subtype`, sebagaimana penyedia memberi label pada entitas."
                },
                "is_direct": {
                  "type": "boolean",
                  "description": "True saat `exposure_type` bernilai `direct`."
                },
                "exposure_direction": {
                  "type": "string",
                  "enum": [
                    "incoming",
                    "outgoing",
                    "connected"
                  ],
                  "description": "Apakah dana berasal dari (`incoming`) atau dikirim ke (`outgoing`) entitas ini."
                },
                "exposure_type": {
                  "type": "string",
                  "enum": [
                    "direct",
                    "indirect"
                  ],
                  "description": "Eksposur `direct` (1 lompatan) atau `indirect` (multi-lompatan)."
                },
                "provider_entity_id": {
                  "type": "string",
                  "nullable": true,
                  "description": "Pengenal milik penyedia sendiri untuk entitas tersebut."
                },
                "provider_entity_type_id": {
                  "type": "string",
                  "nullable": true,
                  "description": "Pengenal milik penyedia sendiri untuk `entity_type`."
                },
                "provider_entity_subtype_id": {
                  "type": "string",
                  "nullable": true,
                  "description": "Pengenal milik penyedia sendiri untuk `entity_subtype`."
                },
                "country": {
                  "type": "string",
                  "nullable": true,
                  "description": "Negara utama entitas berdasarkan ISO 3166-1 alpha-2. Kosong atau `null` ketika penyedia tidak mengetahuinya."
                },
                "raw_amount": {
                  "type": "number",
                  "nullable": true,
                  "description": "Jumlah dalam unit aset itu sendiri, saat penyedia melaporkannya."
                },
                "raw_currency": {
                  "type": "string",
                  "nullable": true,
                  "description": "Satuan dari `raw_amount`, saat penyedia melaporkannya."
                }
              }
            }
          },
          "counterparty_connections": {
            "type": "array",
            "description": "Entitas yang diatribusikan penyedia ke alamat yang diskrining. Untuk Merkle Science, entitas ini berasal dari tag pemilik dan pengguna alamat itu sendiri, sehingga entitas yang sama dapat muncul dua kali, dan tidak membawa aliran dana: `received_usd`, `sent_usd`, `received_hops`, dan `sent_hops` bernilai `null` serta `percentage` adalah 0. Jangan menentukan rute berdasarkan `risk_level` atau `is_direct` di sini: gunakan `sanctions_hit`, `dominant_risk_category`, dan `risk_factors[].is_high_risk` untuk keputusan akhir, serta `exposure_type` di `source_of_funds`/`destination_of_funds` untuk menentukan apakah alirannya langsung.",
            "items": {
              "type": "object",
              "properties": {
                "entity_name": {
                  "type": "string",
                  "nullable": true,
                  "description": "Nama entitas yang diatribusikan."
                },
                "entity_type": {
                  "type": "string",
                  "nullable": true,
                  "description": "Tipe entitas penyedia."
                },
                "entity_subtype": {
                  "type": "string",
                  "nullable": true,
                  "description": "Subtipe entitas penyedia."
                },
                "risk_level": {
                  "type": "string",
                  "description": "Huruf kecil dan bergantung pada penyedia. Untuk Merkle Science, ini adalah tingkat risiko 0-5 milik alamat itu sendiri (`no_risk`, `low`, `medium_low`, `medium`, `high`, `critical`), dinaikkan ke `high` jika kategori entitas berisiko tinggi; ini bukan penilaian terpisah dari entitas."
                },
                "categories": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  },
                  "description": "Kategori risiko entitas yang dinormalisasi."
                },
                "received_usd": {
                  "type": "number",
                  "nullable": true,
                  "description": "USD yang diterima dari entitas, jika dilaporkan oleh penyedia."
                },
                "sent_usd": {
                  "type": "number",
                  "nullable": true,
                  "description": "USD yang dikirimkan ke entitas, jika dilaporkan oleh penyedia."
                },
                "received_hops": {
                  "type": "integer",
                  "nullable": true,
                  "description": "Hop ke entitas di sisi penerima, jika penyedia melaporkannya."
                },
                "sent_hops": {
                  "type": "integer",
                  "nullable": true,
                  "description": "Hop ke entitas di sisi pengirim, jika penyedia melaporkannya."
                },
                "percentage": {
                  "type": "number",
                  "description": "Porsi paparan alamat tersebut, jika penyedia melaporkannya; jika tidak, 0."
                },
                "is_direct": {
                  "type": "boolean",
                  "description": "Selalu `true` untuk Merkle Science, yang koneksinya berupa atribusi alih-alih pihak lawan."
                },
                "country": {
                  "type": "string",
                  "nullable": true,
                  "description": "Negara entitas, jika diketahui."
                },
                "provider_entity_id": {
                  "type": "string",
                  "nullable": true,
                  "description": "Pengenal milik penyedia sendiri untuk entitas tersebut."
                }
              }
            }
          },
          "network_nodes": {
            "type": "array",
            "items": {
              "type": "object"
            },
            "description": "Node graf paparan untuk skrining transaksi. Kosong pada hasil skrining dompet."
          },
          "network_edges": {
            "type": "array",
            "items": {
              "type": "object"
            },
            "description": "Sisi graf paparan untuk skrining transaksi. Kosong pada hasil skrining dompet."
          },
          "sanctions_hit": {
            "type": "boolean",
            "description": "True jika alamat memiliki paparan sanksi langsung atau tidak langsung."
          },
          "pep_counterparty": {
            "type": "boolean",
            "description": "Paparan Politically Exposed Person (PEP). `null` jika tidak ada temuan PEP yang tersedia, yang merupakan semua hasil saat ini karena tidak ada penyedia yang melaporkannya; `false` hanya untuk hasil skrining negatif yang eksplisit. Jangan mengartikan `null` sebagai pemeriksaan PEP yang telah selesai.",
            "nullable": true
          },
          "dominant_risk_category": {
            "type": "string",
            "nullable": true,
            "description": "Kategori berisiko tinggi dengan bobot tertinggi, atau `null` jika tidak ada yang dominan (misalnya `sanctioned`, `mixer`, `stolen_funds`)."
          },
          "risk_factors": {
            "type": "array",
            "description": "Penjelasan berperingkat untuk `risk_score`: faktor apa yang menghasilkan keputusan ini. Penyedia menilai alamat berdasarkan model mereka sendiri dan hanya mengembalikan keputusan (Merkle Science mengembalikan bilangan bulat 0-5), sehingga skor saja tidak dapat ditindaklanjuti. Diurutkan dari risiko tinggi terlebih dahulu, kemudian berdasarkan nilai yang melewati setiap faktor, dibatasi hingga lima yang terkuat; `source_of_funds` dan `destination_of_funds` selalu memuat rincian lengkap. `risk_score` yang tinggi tanpa entri `is_high_risk` berarti penyedia tidak melaporkan adanya kecocokan sanksi atau entitas yang diatribusikan dan menilai alamat murni berdasarkan model eksposurnya sendiri - `summary` menyatakan hal ini secara eksplisit.",
            "items": {
              "type": "object",
              "properties": {
                "source": {
                  "type": "string",
                  "enum": [
                    "attribution",
                    "exposure"
                  ],
                  "description": "`attribution` adalah keterangan penyedia mengenai alamat itu sendiri (label atau clusternya sendiri); `exposure` adalah ke mana dananya sebenarnya berpindah."
                },
                "category": {
                  "type": "string",
                  "description": "Kategori risiko yang dinormalisasi, kosakata yang sama dengan rincian paparan."
                },
                "label": {
                  "type": "string",
                  "description": "Rumusan kata penyedia sendiri untuk faktor (misalnya `Gambling / Crypto only`), yang juga akan Anda lihat di konsol penyedia."
                },
                "entity_name": {
                  "type": "string",
                  "nullable": true,
                  "description": "Entitas yang diatribusikan di balik faktor pendorong, misalnya situs judi atau bursa."
                },
                "direction": {
                  "type": "string",
                  "enum": [
                    "incoming",
                    "outgoing",
                    "connected",
                    "unknown",
                    "attribution"
                  ],
                  "description": "Arah aliran dana, `attribution` saat pemicunya adalah tag milik alamat itu sendiri, atau `unknown` saat penyedia tidak melaporkan arah."
                },
                "exposure_type": {
                  "type": "string",
                  "enum": [
                    "direct",
                    "indirect",
                    "unknown",
                    "attribution"
                  ],
                  "description": "`direct` (1 hop) atau `indirect` (multi-hop), `attribution` untuk tag alamat itu sendiri, atau `unknown` ketika penyedia tidak menyatakan berapa hop jarak pihak lawan. Perlakukan `unknown` sebagai tidak terklasifikasi, bukan sebagai `direct`."
                },
                "amount_usd": {
                  "type": "number",
                  "format": "float",
                  "nullable": true,
                  "description": "Nilai USD yang diatribusikan ke faktor pendorong ini."
                },
                "percentage": {
                  "type": "number",
                  "format": "float",
                  "description": "Porsi dari TOTAL volume yang diskrining pada alamat tersebut, gabungan kedua arah - tidak seperti `percentage` di dalam `source_of_funds`/`destination_of_funds`, yang dinormalisasi per arah. Dapat dibandingkan dan dijumlahkan di seluruh daftar."
                },
                "is_high_risk": {
                  "type": "boolean",
                  "description": "Apakah kategori ini termasuk yang diperlakukan Didit sebagai berisiko tinggi (`sanctioned`, `mixer`, `stolen_funds`, `ransomware`, `scam`, `darknet_market`, `terrorist_financing`, `child_exploitation`, `hacked_exchange`, `high_risk_exchange`, `seized_funds`)."
                },
                "description": {
                  "type": "string",
                  "description": "Representasi satu baris dari faktor pendorong, misalnya `9.01% indirect outgoing exposure to Gambling / Crypto only (Example Gambling)`."
                }
              }
            }
          },
          "raw_response": {
            "type": "object",
            "additionalProperties": true,
            "description": "Payload milik penyedia sendiri. Formatnya spesifik untuk tiap penyedia dan dapat berubah tanpa pemberitahuan: baca kolom yang telah dinormalisasi daripada menguraikannya."
          },
          "report_signature": {
            "type": "string",
            "description": "Tanda tangan HMAC-SHA256 tidak transparan atas hasil persis ini, dengan cakupan ke aplikasi Anda. Tidak memiliki arti tersendiri — kirim ulang seluruh isi respons, tanpa diubah dan termasuk kolom ini, ke `POST /v3/wallet-screening/pdf/` untuk merendernya sebagai PDF. Endpoint PDF menolak permintaan dengan kode `400` jika `report_signature` tidak ada atau jika ada kolom bertanda tangan (misalnya `risk_score`, `severity`, `sanctions_hit`) yang diubah sebelum dikirim ulang."
          }
        },
        "required": [
          "provider",
          "screening_type",
          "risk_score",
          "severity",
          "status",
          "summary",
          "wallet_address",
          "blockchain",
          "sanctions_hit",
          "dominant_risk_category",
          "source_of_funds",
          "destination_of_funds",
          "counterparty_connections",
          "report_signature"
        ]
      },
      "NetworkRiskDisplay": {
        "type": "object",
        "properties": {
          "score": {
            "type": "integer",
            "description": "Skor risiko, 0-100."
          },
          "band": {
            "type": "string",
            "enum": [
              "low",
              "medium",
              "high"
            ],
            "description": "Rentang tampilan skor. high >= 70, medium >= 40, selain itu low."
          },
          "bar": {
            "type": "number",
            "format": "float",
            "description": "Nilai 0-1 yang dinormalisasi untuk menampilkan bilah risiko."
          }
        }
      },
      "NetworkNodeTag": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "color": {
            "type": "string",
            "nullable": true,
            "description": "Null untuk tag guard, yang token warnanya dimiliki oleh renderer."
          },
          "source": {
            "type": "string",
            "enum": [
              "subject_tag",
              "session_tag",
              "transaction_tag",
              "signal_guard"
            ],
            "description": "Asal tag: tag pada pengguna/bisnis, tag pada sesi dalam jaringan ini, tag pada transaksi yang melibatkan suatu pihak, atau kondisi guard sinyal (misalnya hub, IP pusat data)."
          },
          "category": {
            "type": "string",
            "enum": [
              "customer",
              "quality"
            ],
            "nullable": true,
            "description": "customer untuk tag yang ditentukan pelanggan, quality untuk tag pengaman kualitas sinyal. Bernilai null jika tidak berlaku."
          }
        }
      },
      "NetworkListItem": {
        "type": "object",
        "properties": {
          "uuid": {
            "type": "string",
            "format": "uuid"
          },
          "network_id": {
            "type": "string",
            "description": "ID berurutan per organisasi yang dapat dibaca manusia, misalnya N-0001."
          },
          "name": {
            "type": "string",
            "nullable": true
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "in_review",
              "resolved",
              "dismissed"
            ],
            "description": "Status siklus hidup jaringan. Berbeda dari outcome_status per pemohon di dalam jaringan (approved/in_review/declined/not_completed)."
          },
          "risk": {
            "$ref": "#/components/schemas/NetworkRiskDisplay"
          },
          "pattern_types": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "exact_same_device",
                "similar_device",
                "same_ip_address",
                "same_address",
                "similar_selfie_backgrounds",
                "similar_poa_documents",
                "same_document_number",
                "same_phone_number",
                "same_email"
              ]
            },
            "description": "Pola pengelompokan yang terdeteksi di jaringan ini."
          },
          "signal_types": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "ip_address",
                "device",
                "face",
                "document_number",
                "phone",
                "email",
                "address"
              ]
            },
            "description": "Jenis sinyal berbeda yang ada di jaringan ini."
          },
          "member_counts": {
            "type": "object",
            "description": "Jumlah anggota berdasarkan kategori (misalnya total, per outcome_status)."
          },
          "member_status": {
            "type": "object",
            "description": "Rincian anggota berdasarkan outcome_status."
          },
          "signal_coverage": {
            "type": "object",
            "description": "Cakupan per signal_type dari anggota jaringan ini."
          },
          "first_activity_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "last_activity_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          }
        }
      },
      "NetworkDetail": {
        "allOf": [
          {
            "$ref": "#/components/schemas/NetworkListItem"
          },
          {
            "type": "object",
            "properties": {
              "stats": {
                "type": "object",
                "description": "Statistik agregat untuk jaringan (misalnya total anggota)."
              },
              "fraud_tags": {
                "type": "array",
                "items": {
                  "type": "object"
                },
                "description": "Tag pola penipuan yang muncul di jaringan."
              },
              "risk_signals": {
                "type": "object",
                "description": "Ringkasan sinyal risiko: residential_proxy_reuse, email_intelligence, phone_intelligence."
              },
              "reviewed_at": {
                "type": "string",
                "format": "date-time",
                "nullable": true
              },
              "reviewed_by": {
                "type": "string",
                "nullable": true
              },
              "review_reason": {
                "type": "string",
                "nullable": true
              }
            }
          }
        ],
        "properties": {
          "notes_count": {
            "type": "integer",
            "minimum": 0,
            "readOnly": true,
            "description": "Jumlah catatan analis privat dalam investigasi ini."
          }
        }
      },
      "NetworkGraphNode": {
        "type": "object",
        "description": "Node subjek atau node sinyal, dibedakan berdasarkan kind. Node subjek (kind: vendor_user | vendor_business | transaction_party) memuat id, kind, subject, node_status (approved | in_review | declined | not_completed), dan tags. Node sinyal (kind: signal) memuat id, kind, uuid, signal_type, subject_count, coverage, is_hub, is_datacenter_ip, is_high_collision_device, node_status (signal_active | signal_guarded), tags, risk_evidence, first_seen_at, dan last_seen_at.",
        "properties": {
          "id": {
            "type": "string"
          },
          "kind": {
            "type": "string",
            "enum": [
              "vendor_user",
              "vendor_business",
              "transaction_party",
              "signal"
            ]
          }
        }
      },
      "NetworkGraphEdge": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "source": {
            "type": "string",
            "description": "ID node subjek."
          },
          "target": {
            "type": "string",
            "description": "ID node sinyal."
          },
          "subject_kind": {
            "type": "string",
            "enum": [
              "vendor_user",
              "vendor_business",
              "transaction_party"
            ]
          },
          "signal_type": {
            "type": "string",
            "enum": [
              "ip_address",
              "device",
              "face",
              "document_number",
              "phone",
              "email",
              "address"
            ]
          },
          "confidence": {
            "type": "number",
            "format": "float",
            "description": "1.0 untuk kecocokan persis."
          },
          "observation_count": {
            "type": "integer"
          },
          "first_seen_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "last_seen_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          }
        }
      },
      "NetworkGraph": {
        "type": "object",
        "properties": {
          "network": {
            "$ref": "#/components/schemas/NetworkDetail"
          },
          "depth": {
            "type": "integer",
            "nullable": true,
            "description": "Kedalaman efektif yang diterapkan, atau null jika tidak terbatas (depth=all)."
          },
          "truncated": {
            "type": "boolean",
            "description": "True jika lingkungan sekitar dipangkas berdasarkan kedalaman."
          },
          "nodes": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/NetworkGraphNode"
            }
          },
          "edges": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/NetworkGraphEdge"
            }
          },
          "metrics": {
            "type": "object",
            "properties": {
              "node_count": {
                "type": "integer"
              },
              "edge_count": {
                "type": "integer"
              },
              "hub_signal_count": {
                "type": "integer"
              }
            }
          }
        }
      },
      "NetworkMember": {
        "type": "object",
        "properties": {
          "subject": {
            "type": "object",
            "description": "vendor_user, vendor_business, atau transaction_party yang diwakili oleh anggota ini."
          },
          "outcome_status": {
            "type": "string",
            "description": "Hasil verifikasi/keputusan subjek."
          },
          "node_status": {
            "type": "string",
            "enum": [
              "approved",
              "in_review",
              "declined",
              "not_completed",
              "signal_active",
              "signal_guarded"
            ],
            "description": "Untuk baris anggota, ini selalu merupakan salah satu dari nilai hasil subjek: approved, in_review, declined, atau not_completed."
          },
          "tags": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/NetworkNodeTag"
            }
          },
          "risk": {
            "$ref": "#/components/schemas/NetworkRiskDisplay"
          },
          "signal_coverage": {
            "type": "object"
          },
          "shared_infrastructure": {
            "type": "object"
          },
          "joined_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "last_seen_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "provenance": {
            "type": "object",
            "properties": {
              "session_ids": {
                "type": "array",
                "items": {
                  "type": "string",
                  "format": "uuid"
                }
              },
              "business_session_ids": {
                "type": "array",
                "items": {
                  "type": "string",
                  "format": "uuid"
                }
              },
              "transaction_ids": {
                "type": "array",
                "items": {
                  "type": "string",
                  "format": "uuid"
                }
              }
            }
          }
        }
      },
      "NetworkSignal": {
        "type": "object",
        "properties": {
          "uuid": {
            "type": "string",
            "format": "uuid"
          },
          "signal_type": {
            "type": "string",
            "enum": [
              "ip_address",
              "device",
              "face",
              "document_number",
              "phone",
              "email",
              "address"
            ]
          },
          "subject_count": {
            "type": "integer"
          },
          "coverage": {
            "type": "number",
            "format": "float"
          },
          "is_hub": {
            "type": "boolean",
            "description": "True jika sinyal ini menautkan subjek dalam jumlah yang tidak biasa besarnya."
          },
          "is_datacenter_ip": {
            "type": "boolean"
          },
          "is_high_collision_device": {
            "type": "boolean"
          },
          "node_status": {
            "type": "string",
            "enum": [
              "signal_active",
              "signal_guarded"
            ]
          },
          "tags": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/NetworkNodeTag"
            }
          },
          "risk_evidence": {
            "type": "object"
          },
          "first_seen_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "last_seen_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          }
        }
      },
      "NetworkTimelineEvent": {
        "type": "object",
        "properties": {
          "event_type": {
            "type": "string",
            "description": "misalnya network_detected, signal_observed, network_in_review, network_resolved, network_dismissed."
          },
          "occurred_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "label": {
            "type": "string"
          },
          "metadata": {
            "type": "object"
          }
        }
      },
      "NetworkMap": {
        "type": "object",
        "properties": {
          "network": {
            "$ref": "#/components/schemas/NetworkDetail"
          },
          "convergence_count": {
            "type": "integer",
            "description": "Jumlah titik alamat/lokasi berbeda yang menjadi tempat berkumpulnya para anggota."
          },
          "countries": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "points": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "uuid": {
                  "type": "string",
                  "format": "uuid"
                },
                "country": {
                  "type": "string",
                  "nullable": true
                },
                "country_code": {
                  "type": "string",
                  "nullable": true
                },
                "city": {
                  "type": "string",
                  "nullable": true
                },
                "latitude": {
                  "type": "number",
                  "format": "float",
                  "nullable": true
                },
                "longitude": {
                  "type": "number",
                  "format": "float",
                  "nullable": true
                },
                "observed_at": {
                  "type": "string",
                  "format": "date-time",
                  "nullable": true
                }
              }
            }
          }
        }
      },
      "EntityNetworkMembership": {
        "type": "object",
        "properties": {
          "network": {
            "$ref": "#/components/schemas/NetworkListItem"
          },
          "subject": {
            "type": "object"
          },
          "signal_types": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "ip_address",
                "device",
                "face",
                "document_number",
                "phone",
                "email",
                "address"
              ]
            }
          },
          "signal_count": {
            "type": "integer"
          },
          "joined_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "last_seen_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          }
        }
      },
      "RiskSignals": {
        "type": "object",
        "description": "Konteks perangkat dan jaringan opsional yang diamati oleh aplikasi Anda. Semua kolom bersifat opsional. Meneruskannya akan menyediakan data untuk deteksi kecocokan lintas sesi di Networks.",
        "properties": {
          "ip": {
            "type": "string",
            "format": "ip",
            "description": "Alamat IPv4 atau IPv6 yang teramati untuk pengguna akhir.",
            "example": "192.0.2.1"
          },
          "device_id": {
            "type": "string",
            "maxLength": 255,
            "description": "Pengidentifikasi perangkat stabil yang dikumpulkan oleh aplikasi Anda (`ANDROID_ID` Android, `identifierForVendor` iOS)."
          },
          "device_platform": {
            "type": "string",
            "enum": [
              "android",
              "ios",
              "ipados",
              "tvos",
              "web"
            ],
            "description": "Platform perangkat pengguna akhir."
          },
          "device_model": {
            "type": "string",
            "maxLength": 255,
            "description": "Model perangkat yang dilaporkan oleh aplikasi Anda."
          },
          "os_version": {
            "type": "string",
            "maxLength": 64,
            "description": "Versi sistem operasi."
          },
          "app_version": {
            "type": "string",
            "maxLength": 64,
            "description": "Versi aplikasi Anda."
          },
          "user_agent": {
            "type": "string",
            "maxLength": 512,
            "description": "User agent browser atau aplikasi."
          }
        }
      },
      "PhoneRiskRequest": {
        "type": "object",
        "required": [
          "phone_number"
        ],
        "properties": {
          "phone_number": {
            "type": "string",
            "maxLength": 20,
            "description": "Nomor telepon untuk dinilai. Nomor divalidasi dan dinormalisasi ke E.164.",
            "example": "+14155552671"
          },
          "country_code": {
            "type": "string",
            "maxLength": 3,
            "description": "Petunjuk negara ISO 3166-1 alpha-2 atau alpha-3 opsional untuk cakupan intelijen.",
            "example": "US"
          },
          "signals": {
            "$ref": "#/components/schemas/RiskSignals"
          },
          "vendor_data": {
            "type": "string",
            "description": "Referensi stabil Anda untuk permintaan ini. Disimpan pada sesi API dan ditampilkan kembali dalam respons."
          },
          "metadata": {
            "type": "object",
            "nullable": true,
            "additionalProperties": true,
            "description": "Metadata JSON non-sensitif Anda. Disimpan pada sesi API dan dikembalikan dalam respons."
          },
          "enable_social": {
            "type": "boolean",
            "default": false,
            "description": "Jika true, cari juga jejak sosial nomor tersebut - platform perpesanan, sosial, e-commerce, dan profesional tempat nomor tersebut terdaftar. Ditagih sebagai satu unit `phone_social` per permintaan selain harga endpoint ini sendiri.",
            "example": true
          }
        }
      },
      "EmailRiskRequest": {
        "type": "object",
        "required": [
          "email"
        ],
        "properties": {
          "email": {
            "type": "string",
            "format": "email",
            "description": "Alamat email yang akan diberi skor.",
            "example": "alice@example.com"
          },
          "country_code": {
            "type": "string",
            "maxLength": 3,
            "description": "Petunjuk negara ISO 3166-1 alpha-2 atau alpha-3 opsional untuk cakupan intelijen.",
            "example": "US"
          },
          "signals": {
            "$ref": "#/components/schemas/RiskSignals"
          },
          "vendor_data": {
            "type": "string",
            "description": "Referensi stabil Anda untuk permintaan ini. Disimpan pada sesi API dan ditampilkan kembali dalam respons."
          },
          "metadata": {
            "type": "object",
            "nullable": true,
            "additionalProperties": true,
            "description": "Metadata JSON non-sensitif Anda. Disimpan pada sesi API dan dikembalikan dalam respons."
          },
          "enable_social": {
            "type": "boolean",
            "default": false,
            "description": "Jika true, cari juga jejak sosial alamat tersebut - platform email, sosial, profesional, e-commerce, dan hiburan tempat alamat tersebut terdaftar. Ditagih sebagai satu unit `email_social` per permintaan selain harga endpoint ini sendiri.",
            "example": true
          }
        }
      },
      "IPRiskRequest": {
        "type": "object",
        "required": [
          "ip_address"
        ],
        "properties": {
          "ip_address": {
            "type": "string",
            "format": "ip",
            "description": "Alamat IPv4 atau IPv6 yang akan dinilai.",
            "example": "8.8.8.8"
          },
          "claimed_country": {
            "type": "string",
            "maxLength": 3,
            "description": "Negara ISO 3166-1 alpha-2 atau alpha-3 opsional yang diklaim oleh pengguna atau sesi. Digunakan untuk menghitung `country_mismatch`.",
            "example": "ESP"
          },
          "user_agent": {
            "type": "string",
            "maxLength": 512,
            "description": "User agent yang diamati oleh backend Anda. Disimpan sebagai konteks permintaan; ini tidak menyediakan fingerprinting perangkat."
          },
          "vendor_data": {
            "type": "string",
            "description": "Referensi stabil Anda untuk permintaan ini. Disimpan pada sesi API dan ditampilkan kembali dalam respons."
          },
          "metadata": {
            "type": "object",
            "nullable": true,
            "additionalProperties": true,
            "description": "Metadata JSON non-sensitif Anda. Disimpan pada sesi API dan dikembalikan dalam respons."
          }
        }
      },
      "RiskWarning": {
        "type": "object",
        "required": [
          "feature",
          "risk",
          "log_type",
          "short_description",
          "long_description"
        ],
        "properties": {
          "feature": {
            "type": "string",
            "description": "Fitur yang menghasilkan peringatan."
          },
          "risk": {
            "type": "string",
            "description": "Kode risiko yang dapat dibaca mesin. Nilai baru dapat ditambahkan seiring waktu."
          },
          "additional_data": {
            "type": "object",
            "nullable": true,
            "additionalProperties": true,
            "description": "Konteks spesifik risiko, atau `null`."
          },
          "log_type": {
            "type": "string",
            "enum": [
              "error",
              "warning",
              "information"
            ],
            "description": "Tingkat keparahan yang digunakan oleh aturan keputusan."
          },
          "short_description": {
            "type": "string",
            "description": "Ringkasan satu baris yang dapat dibaca manusia."
          },
          "long_description": {
            "type": "string",
            "description": "Penjelasan yang mudah dibaca manusia."
          }
        }
      },
      "RiskLifecycleEvent": {
        "type": "object",
        "required": [
          "type",
          "timestamp",
          "details",
          "fee"
        ],
        "properties": {
          "type": {
            "type": "string",
            "description": "Tipe event yang dapat dibaca mesin. Nilai-nilai baru dapat ditambahkan seiring waktu."
          },
          "timestamp": {
            "type": "string",
            "format": "date-time",
            "description": "Waktu ketika peristiwa terjadi."
          },
          "details": {
            "type": "object",
            "nullable": true,
            "additionalProperties": true,
            "description": "Payload khusus event, atau `null`."
          },
          "fee": {
            "type": "number",
            "description": "Jumlah USD yang ditagihkan untuk event ini."
          }
        }
      },
      "PhoneMatchItem": {
        "type": "object",
        "description": "Sesi lain dari aplikasi Anda yang menggunakan nomor telepon yang sama dengan `vendor_data` yang berbeda.",
        "properties": {
          "session_id": {
            "type": "string",
            "format": "uuid",
            "description": "ID sesi dari verifikasi lain yang menggunakan nomor telepon ini."
          },
          "session_number": {
            "type": "integer",
            "description": "Nomor urut sesi yang mudah dibaca manusia."
          },
          "vendor_data": {
            "type": "string",
            "nullable": true,
            "description": "`vendor_data` dari sesi tersebut."
          },
          "verification_date": {
            "type": "string",
            "description": "Waktu ketika sesi tersebut dibuat (`YYYY-MM-DDTHH:MM:SSZ`)."
          },
          "phone_number": {
            "type": "string",
            "description": "Nomor telepon yang cocok."
          },
          "status": {
            "type": "string",
            "description": "Status sesi tersebut (misalnya, `Approved`, `Declined`, `In Progress`)."
          },
          "is_blocklisted": {
            "type": "boolean",
            "description": "Apakah nomor telepon ada di daftar blokir aplikasi Anda."
          },
          "api_service": {
            "type": "string",
            "nullable": true,
            "description": "Untuk sesi bertipe API, API mandiri yang membuatnya; `null` untuk sesi verifikasi reguler."
          },
          "source": {
            "type": "string",
            "description": "Tempat kecocokan ditemukan. Biasanya `session`; kecocokan daftar blokir melalui entri daftar organisasi menggunakan `list_entry`."
          }
        }
      },
      "EmailMatchItem": {
        "type": "object",
        "description": "Sesi lain dari aplikasi Anda yang menggunakan alamat email yang sama dengan `vendor_data` yang berbeda.",
        "properties": {
          "session_id": {
            "type": "string",
            "format": "uuid",
            "description": "ID sesi dari verifikasi lain yang menggunakan alamat email ini."
          },
          "session_number": {
            "type": "integer",
            "description": "Nomor urut sesi yang mudah dibaca manusia."
          },
          "vendor_data": {
            "type": "string",
            "nullable": true,
            "description": "`vendor_data` dari sesi tersebut."
          },
          "verification_date": {
            "type": "string",
            "description": "Waktu ketika sesi tersebut dibuat (`YYYY-MM-DDTHH:MM:SSZ`)."
          },
          "email": {
            "type": "string",
            "description": "Alamat email yang cocok."
          },
          "status": {
            "type": "string",
            "description": "Status sesi tersebut (misalnya, `Approved`, `Declined`, `In Progress`)."
          },
          "is_blocklisted": {
            "type": "boolean",
            "description": "Apakah alamat email ada di daftar blokir aplikasi Anda."
          },
          "api_service": {
            "type": "string",
            "nullable": true,
            "description": "Untuk sesi bertipe API, API mandiri yang membuatnya; `null` untuk sesi verifikasi reguler."
          },
          "source": {
            "type": "string",
            "description": "Tempat kecocokan ditemukan. Biasanya `session`; kecocokan daftar blokir melalui entri daftar organisasi menggunakan `list_entry`."
          }
        }
      },
      "PhoneIntelligence": {
        "type": "object",
        "description": "Blok intelijen telepon yang dinormalisasi. Hanya ada ketika add-on intelijen dijalankan untuk pencarian ini; jika ada, ini juga diekspos di bawah alias `enrichment` dengan nilai yang identik.",
        "properties": {
          "score": {
            "type": "number",
            "nullable": true,
            "description": "Skor risiko 0-100 yang dinormalisasi. Lebih tinggi berarti lebih berisiko."
          },
          "phone_type_risk": {
            "type": "string",
            "nullable": true,
            "description": "`Low`, `Medium`, atau `High`, diperoleh dari skor."
          },
          "phone_trust_index": {
            "type": "number",
            "nullable": true,
            "description": "Kebalikan dari skor, untuk dasbor yang memilih semakin tinggi semakin baik."
          },
          "network_stability_index": {
            "type": "number",
            "nullable": true,
            "description": "Stabilitas jaringan lini tersebut."
          },
          "is_disposable": {
            "type": "boolean",
            "nullable": true,
            "description": "`true` saat nomor tampak sekali pakai atau virtual."
          },
          "is_ported": {
            "type": "boolean",
            "nullable": true,
            "description": "`true` saat nomor telah berganti operator."
          },
          "is_recently_ported": {
            "type": "boolean",
            "nullable": true,
            "description": "`true` saat pemindahan nomor (port) baru saja terjadi."
          },
          "carrier_type": {
            "type": "string",
            "nullable": true,
            "description": "Klasifikasi saluran yang dilaporkan oleh pencarian (misalnya, `mobile`)."
          },
          "reason_codes": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "code": {
                  "type": "string",
                  "description": "Pengidentifikasi Didit yang stabil untuk sinyal tersebut, misalnya `IR-5AC67A32`. Tidak transparan: kelompokkan dan filter berdasarkan nilai ini, jangan menguraikannya."
                },
                "value": {
                  "nullable": true,
                  "description": "Untuk flag risiko (misalnya `voip`, `leaked`, `disposable`, `spam_trap`), nilainya: boolean, level, atau tanggal. Null untuk kode alasan dengan skor."
                },
                "direction": {
                  "type": "string",
                  "enum": [
                    "risk",
                    "trust"
                  ],
                  "description": "Apakah sinyal meningkatkan risiko atau menambah kepercayaan."
                },
                "message": {
                  "type": "string",
                  "description": "Penjelasan sinyal yang mudah dibaca manusia, dalam bahasa Inggris."
                },
                "impact_level": {
                  "type": "string",
                  "nullable": true,
                  "description": "Seberapa kuat sinyal tersebut memengaruhi skor, misalnya `low`, `medium`, atau `high`."
                }
              }
            },
            "description": "Sinyal yang menjelaskan skor tersebut, masing-masing dengan kode Didit yang stabil, arah, pesan, dan tingkat dampak. Kode baru dapat muncul sewaktu-waktu, jadi jangan tolak kode yang tidak dikenal."
          }
        }
      },
      "EmailIntelligence": {
        "type": "object",
        "description": "Blok intelijen email yang dinormalisasi. Hanya ada ketika add-on intelijen dijalankan untuk email ini; jika ada, ini juga diekspos sebagai alias `enrichment` dengan nilai yang identik.",
        "properties": {
          "score": {
            "type": "number",
            "nullable": true,
            "description": "Skor risiko 0-100 yang dinormalisasi. Lebih tinggi berarti lebih berisiko."
          },
          "deliverable": {
            "type": "string",
            "nullable": true,
            "description": "Tingkat keterkiriman (misalnya, `high`)."
          },
          "breach_risk_level": {
            "type": "string",
            "nullable": true,
            "description": "`Low`, `Medium`, atau `High`."
          },
          "breach_risk_index": {
            "type": "number",
            "nullable": true,
            "description": "Indeks risiko pelanggaran numerik."
          },
          "is_recent_breach": {
            "type": "boolean",
            "nullable": true,
            "description": "`true` jika alamat muncul dalam kebocoran data terkini."
          },
          "is_frequent_breached": {
            "type": "boolean",
            "nullable": true,
            "description": "`true` jika alamat muncul dalam banyak kebocoran data."
          },
          "is_disposable": {
            "type": "boolean",
            "nullable": true,
            "description": "`true` saat domain merupakan penyedia email sekali pakai."
          },
          "is_free_domain": {
            "type": "boolean",
            "nullable": true,
            "description": "`true` saat domain merupakan penyedia email gratis."
          },
          "is_breached": {
            "type": "boolean",
            "nullable": true,
            "description": "`true` jika alamat muncul dalam kebocoran data yang diketahui."
          },
          "no_of_breaches": {
            "type": "number",
            "nullable": true,
            "description": "Jumlah kebocoran data yang diketahui yang memuat alamat tersebut."
          },
          "reason_codes": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "code": {
                  "type": "string",
                  "description": "Pengidentifikasi Didit yang stabil untuk sinyal tersebut, misalnya `IR-5AC67A32`. Tidak transparan: kelompokkan dan filter berdasarkan nilai ini, jangan menguraikannya."
                },
                "value": {
                  "nullable": true,
                  "description": "Untuk flag risiko (misalnya `voip`, `leaked`, `disposable`, `spam_trap`), nilainya: boolean, level, atau tanggal. Null untuk kode alasan dengan skor."
                },
                "direction": {
                  "type": "string",
                  "enum": [
                    "risk",
                    "trust"
                  ],
                  "description": "Apakah sinyal meningkatkan risiko atau menambah kepercayaan."
                },
                "message": {
                  "type": "string",
                  "description": "Penjelasan sinyal yang mudah dibaca manusia, dalam bahasa Inggris."
                },
                "impact_level": {
                  "type": "string",
                  "nullable": true,
                  "description": "Seberapa kuat sinyal tersebut memengaruhi skor, misalnya `low`, `medium`, atau `high`."
                }
              }
            },
            "description": "Sinyal yang menjelaskan skor tersebut, masing-masing dengan kode Didit yang stabil, arah, pesan, dan tingkat dampak. Kode baru dapat muncul sewaktu-waktu, jadi jangan tolak kode yang tidak dikenal."
          }
        }
      },
      "IPRiskResult": {
        "type": "object",
        "description": "Hasil risiko IP. Kolom pengayaan individual dapat bernilai `null` jika pencarian tidak mengembalikan data yang dapat digunakan.",
        "required": [
          "status",
          "threat"
        ],
        "properties": {
          "status": {
            "type": "string",
            "enum": [
              "Approved",
              "In Review"
            ],
            "description": "`In Review` ketika negara yang teridentifikasi bertentangan dengan `claimed_country`, atau ketika alamat dikaitkan dengan infrastruktur VPN, Tor, atau pusat data. Jika tidak, `Approved`."
          },
          "ip_address": {
            "type": "string",
            "nullable": true,
            "description": "Alamat yang dinilai. `null` jika tidak ada sumber pengayaan yang mengembalikan data yang dapat digunakan."
          },
          "ip_country": {
            "type": "string",
            "nullable": true,
            "description": "Nama negara hasil resolusi."
          },
          "ip_country_code": {
            "type": "string",
            "nullable": true,
            "description": "Kode negara yang terselesaikan. Bandingkan negara melalui `country_mismatch` alih-alih membandingkan string negara mentah sendiri."
          },
          "ip_state": {
            "type": "string",
            "nullable": true,
            "description": "Negara bagian atau wilayah hasil resolusi."
          },
          "ip_city": {
            "type": "string",
            "nullable": true,
            "description": "Kota hasil resolusi."
          },
          "latitude": {
            "type": "number",
            "nullable": true,
            "description": "Geolokasi jaringan perkiraan, bukan lokasi perangkat yang presisi."
          },
          "longitude": {
            "type": "number",
            "nullable": true,
            "description": "Geolokasi jaringan perkiraan, bukan lokasi perangkat yang presisi."
          },
          "isp": {
            "type": "string",
            "nullable": true,
            "description": "Penyedia layanan internet yang melayani alamat tersebut."
          },
          "organization": {
            "type": "string",
            "nullable": true,
            "description": "Organisasi yang memiliki blok alamat."
          },
          "is_vpn_or_tor": {
            "type": "boolean",
            "nullable": true,
            "description": "`true` jika alamat dikaitkan dengan infrastruktur VPN atau Tor."
          },
          "is_data_center": {
            "type": "boolean",
            "nullable": true,
            "description": "`true` jika alamat termasuk dalam jaringan hosting atau pusat data."
          },
          "time_zone": {
            "type": "string",
            "nullable": true,
            "description": "Zona waktu dari lokasi hasil resolusi."
          },
          "time_zone_offset": {
            "type": "string",
            "nullable": true,
            "description": "Offset UTC dari lokasi yang ditentukan."
          },
          "asn_number": {
            "type": "number",
            "nullable": true,
            "description": "Nomor sistem otonom."
          },
          "asn_organization": {
            "type": "string",
            "nullable": true,
            "description": "Organisasi yang mengoperasikan sistem otonom."
          },
          "connection_type": {
            "type": "string",
            "nullable": true,
            "description": "Klasifikasi koneksi (misalnya, `cellular`, `hosting`)."
          },
          "carrier": {
            "type": "string",
            "nullable": true,
            "description": "Operator seluler ketika alamat berada di jaringan seluler."
          },
          "proxy_type": {
            "type": "string",
            "nullable": true,
            "description": "Klasifikasi proksi saat alamat berada di balik proksi."
          },
          "claimed_country": {
            "type": "string",
            "nullable": true,
            "description": "Salinan `claimed_country` yang Anda kirimkan."
          },
          "country_mismatch": {
            "type": "boolean",
            "nullable": true,
            "description": "`true` saat negara yang teridentifikasi berbeda dari `claimed_country`. `null` saat tidak ada data pengayaan atau tidak ada negara yang diklaim yang tersedia."
          },
          "threat": {
            "type": "object",
            "additionalProperties": true,
            "description": "Bukti ancaman jaringan bentuk bebas dari sumber pengayaan (misalnya, `is_proxy`, `is_tor`). Objek kosong jika tidak ada data pengayaan yang tersedia. Perlakukan sebagai detail diagnostik, bukan kontrak yang stabil."
          }
        }
      },
      "PhoneRiskResponse": {
        "type": "object",
        "required": [
          "request_id",
          "status",
          "created_at"
        ],
        "properties": {
          "request_id": {
            "type": "string",
            "format": "uuid",
            "description": "Id dari sesi API yang dibuat untuk permintaan ini. Simpan bersama `vendor_data` jika Anda perlu mengorelasikan hasilnya dengan webhook atau aktivitas konsol berikutnya."
          },
          "status": {
            "type": "string",
            "enum": [
              "Approved",
              "In Review",
              "Declined"
            ],
            "description": "Keputusan akhir untuk sesi API ini. Biasanya `Approved`; evaluasi risiko dapat menghasilkan `In Review` atau `Declined`."
          },
          "vendor_data": {
            "type": "string",
            "nullable": true,
            "description": "Salinan `vendor_data` yang Anda kirimkan, atau `null` jika Anda tidak mengirimkannya."
          },
          "metadata": {
            "type": "object",
            "nullable": true,
            "additionalProperties": true,
            "description": "Salinan `metadata` yang Anda kirimkan, atau `null` jika Anda tidak mengirimkannya."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "Cap waktu respons ini."
          },
          "phone": {
            "type": "object",
            "description": "Laporan telepon yang dinormalisasi, blok yang sama yang digunakan oleh respons Verifikasi Telepon.",
            "required": [
              "status"
            ],
            "properties": {
              "status": {
                "type": "string",
                "enum": [
                  "Approved",
                  "In Review",
                  "Declined"
                ],
                "description": "Keputusan untuk nomor telepon ini. Mencerminkan `status` tingkat teratas."
              },
              "phone_number_prefix": {
                "type": "string",
                "description": "Kode panggilan negara dengan awalan `+` (misalnya, `+1`).",
                "example": "+1"
              },
              "phone_number": {
                "type": "string",
                "description": "Nomor nasional tanpa kode panggilan negara.",
                "example": "4155552671"
              },
              "full_number": {
                "type": "string",
                "description": "Nomor lengkap dalam format E.164.",
                "example": "+14155552671"
              },
              "country_code": {
                "type": "string",
                "nullable": true,
                "description": "Negara ISO 3166-1 alpha-2 dari nomor tersebut.",
                "example": "US"
              },
              "country_name": {
                "type": "string",
                "description": "Nama lengkap negara yang diturunkan dari `country_code`.",
                "example": "United States"
              },
              "carrier": {
                "type": "object",
                "nullable": true,
                "description": "Jaringan saat ini yang melayani nomor tersebut. `null` jika pencarian tidak dapat menemukan operator.",
                "properties": {
                  "name": {
                    "type": "string",
                    "description": "Nama operator. String kosong jika pencarian tidak dapat mengidentifikasinya."
                  },
                  "type": {
                    "type": "string",
                    "description": "Jenis saluran yang dilaporkan oleh pencarian: `mobile`, `fixed_line`, `voip`, `isp`, `vpn`, `toll_free`, `premium_rate`, atau serupa."
                  }
                }
              },
              "is_disposable": {
                "type": "boolean",
                "description": "`true` saat nomor tersebut milik layanan nomor sementara atau sekali pakai."
              },
              "is_virtual": {
                "type": "boolean",
                "description": "`true` saat jenis saluran bersifat virtual (`voip`, `isp`, atau `vpn`)."
              },
              "verification_method": {
                "type": "string",
                "nullable": true,
                "description": "Saluran OTP untuk verifikasi yang mendasarinya. `null` untuk pencarian risiko, yang tidak pernah mengirimkan kode."
              },
              "verification_attempts": {
                "type": "integer",
                "description": "Pengiriman OTP untuk nomor ini. `0` untuk pencarian risiko."
              },
              "verified_at": {
                "type": "string",
                "format": "date-time",
                "nullable": true,
                "description": "Waktu nomor terakhir diverifikasi dengan OTP. `null` untuk pencarian risiko."
              },
              "warnings": {
                "type": "array",
                "description": "Peringatan risiko yang dicatat untuk permintaan ini. Berupa array kosong jika tidak ada.",
                "items": {
                  "$ref": "#/components/schemas/RiskWarning"
                }
              },
              "lifecycle": {
                "type": "array",
                "description": "Jejak audit kronologis dari permintaan. Berupa array kosong untuk pencarian risiko tanpa event pengiriman.",
                "items": {
                  "$ref": "#/components/schemas/RiskLifecycleEvent"
                }
              },
              "matches": {
                "type": "array",
                "description": "Sesi lain dari aplikasi Anda tempat nomor telepon yang sama digunakan oleh pengguna berbeda (`vendor_data` berbeda). Hingga 5 entri. Array kosong jika tidak ada kecocokan.",
                "items": {
                  "$ref": "#/components/schemas/PhoneMatchItem"
                }
              },
              "phone_intelligence": {
                "$ref": "#/components/schemas/PhoneIntelligence"
              },
              "enrichment": {
                "$ref": "#/components/schemas/PhoneIntelligence"
              },
              "phone_social": {
                "$ref": "#/components/schemas/PhoneSocialFootprint"
              }
            }
          }
        }
      },
      "EmailRiskResponse": {
        "type": "object",
        "required": [
          "request_id",
          "status",
          "created_at"
        ],
        "properties": {
          "request_id": {
            "type": "string",
            "format": "uuid",
            "description": "Id dari sesi API yang dibuat untuk permintaan ini. Simpan bersama `vendor_data` jika Anda perlu mengorelasikan hasilnya dengan webhook atau aktivitas konsol berikutnya."
          },
          "status": {
            "type": "string",
            "enum": [
              "Approved",
              "In Review",
              "Declined"
            ],
            "description": "Keputusan akhir untuk sesi API ini. Biasanya `Approved`; evaluasi risiko dapat menghasilkan `In Review` atau `Declined`."
          },
          "vendor_data": {
            "type": "string",
            "nullable": true,
            "description": "Salinan `vendor_data` yang Anda kirimkan, atau `null` jika Anda tidak mengirimkannya."
          },
          "metadata": {
            "type": "object",
            "nullable": true,
            "additionalProperties": true,
            "description": "Salinan `metadata` yang Anda kirimkan, atau `null` jika Anda tidak mengirimkannya."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "Cap waktu respons ini."
          },
          "email": {
            "type": "object",
            "description": "Laporan email yang dinormalisasi, blok yang sama yang digunakan oleh respons Verifikasi Email.",
            "required": [
              "status",
              "email",
              "is_breached",
              "breaches",
              "is_disposable",
              "is_undeliverable"
            ],
            "properties": {
              "status": {
                "type": "string",
                "enum": [
                  "Approved",
                  "In Review",
                  "Declined"
                ],
                "description": "Keputusan untuk alamat email ini. Mencerminkan `status` tingkat teratas."
              },
              "email": {
                "type": "string",
                "description": "Alamat yang dinilai.",
                "example": "alice@example.com"
              },
              "is_breached": {
                "type": "boolean",
                "description": "Apakah alamat muncul dalam kebocoran kredensial yang diketahui."
              },
              "breaches": {
                "type": "array",
                "description": "Hingga 5 kebocoran data terbaru yang diketahui berisi alamat ini. Larik kosong jika `is_breached` bernilai `false`.",
                "items": {
                  "type": "object",
                  "properties": {
                    "name": {
                      "type": "string",
                      "description": "Pengidentifikasi pelanggaran."
                    },
                    "domain": {
                      "type": "string",
                      "description": "Domain dari layanan yang mengalami kebocoran data."
                    },
                    "breach_date": {
                      "type": "string",
                      "format": "date",
                      "description": "Tanggal pelanggaran terjadi."
                    },
                    "breach_emails_count": {
                      "type": "integer",
                      "description": "Jumlah total akun yang terekspos dalam pelanggaran data."
                    },
                    "description": {
                      "type": "string",
                      "description": "Deskripsi pelanggaran yang mudah dibaca manusia (dapat berisi markup HTML)."
                    },
                    "logo_path": {
                      "type": "string",
                      "description": "URL logo layanan yang mengalami kebocoran data."
                    },
                    "data_classes": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Kategori data yang terekspos, dalam snake_case (misalnya, `email_addresses`, `passwords`)."
                    },
                    "is_verified": {
                      "type": "boolean",
                      "description": "Apakah pelanggaran telah diverifikasi sebagai sah."
                    }
                  }
                }
              },
              "is_disposable": {
                "type": "boolean",
                "description": "Apakah domain milik penyedia sekali pakai."
              },
              "is_undeliverable": {
                "type": "boolean",
                "description": "Apakah alamat dinyatakan tidak dapat dikirim."
              },
              "verification_attempts": {
                "type": "integer",
                "description": "Pengiriman OTP untuk alamat ini. `0` untuk pencarian risiko."
              },
              "verified_at": {
                "type": "string",
                "format": "date-time",
                "nullable": true,
                "description": "Waktu ketika alamat terakhir diverifikasi melalui OTP. `null` untuk pencarian risiko."
              },
              "warnings": {
                "type": "array",
                "description": "Peringatan risiko yang dicatat untuk permintaan ini. Berupa array kosong jika tidak ada.",
                "items": {
                  "$ref": "#/components/schemas/RiskWarning"
                }
              },
              "lifecycle": {
                "type": "array",
                "description": "Jejak audit kronologis dari permintaan. Berupa array kosong untuk pencarian risiko tanpa pengiriman.",
                "items": {
                  "$ref": "#/components/schemas/RiskLifecycleEvent"
                }
              },
              "matches": {
                "type": "array",
                "description": "Sesi lain dari aplikasi Anda tempat alamat email yang sama digunakan oleh pengguna berbeda (`vendor_data` berbeda). Hingga 5 entri. Array kosong jika tidak ada kecocokan.",
                "items": {
                  "$ref": "#/components/schemas/EmailMatchItem"
                }
              },
              "email_intelligence": {
                "$ref": "#/components/schemas/EmailIntelligence"
              },
              "enrichment": {
                "$ref": "#/components/schemas/EmailIntelligence"
              },
              "email_social": {
                "$ref": "#/components/schemas/EmailSocialFootprint"
              }
            }
          }
        }
      },
      "IPRiskResponse": {
        "type": "object",
        "required": [
          "request_id",
          "status",
          "created_at"
        ],
        "properties": {
          "request_id": {
            "type": "string",
            "format": "uuid",
            "description": "Id dari sesi API yang dibuat untuk permintaan ini. Simpan bersama `vendor_data` jika Anda perlu mengorelasikan hasilnya dengan webhook atau aktivitas konsol berikutnya."
          },
          "status": {
            "type": "string",
            "enum": [
              "Approved",
              "In Review"
            ],
            "description": "Keputusan untuk sesi API ini: `In Review` untuk risiko jaringan atau ketidakcocokan negara, jika tidak maka `Approved`."
          },
          "vendor_data": {
            "type": "string",
            "nullable": true,
            "description": "Salinan `vendor_data` yang Anda kirimkan, atau `null` jika Anda tidak mengirimkannya."
          },
          "metadata": {
            "type": "object",
            "nullable": true,
            "additionalProperties": true,
            "description": "Salinan `metadata` yang Anda kirimkan, atau `null` jika Anda tidak mengirimkannya."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "Cap waktu respons ini."
          },
          "ip": {
            "type": "object",
            "description": "Hasil risiko IP. Kolom pengayaan individual dapat bernilai `null` jika pencarian tidak mengembalikan data yang dapat digunakan.",
            "required": [
              "status",
              "threat"
            ],
            "properties": {
              "status": {
                "type": "string",
                "enum": [
                  "Approved",
                  "In Review"
                ],
                "description": "`In Review` ketika negara yang teridentifikasi bertentangan dengan `claimed_country`, atau ketika alamat dikaitkan dengan infrastruktur VPN, Tor, atau pusat data. Jika tidak, `Approved`."
              },
              "ip_address": {
                "type": "string",
                "nullable": true,
                "description": "Alamat yang dinilai. `null` jika tidak ada sumber pengayaan yang mengembalikan data yang dapat digunakan."
              },
              "ip_country": {
                "type": "string",
                "nullable": true,
                "description": "Nama negara hasil resolusi."
              },
              "ip_country_code": {
                "type": "string",
                "nullable": true,
                "description": "Kode negara yang terselesaikan. Bandingkan negara melalui `country_mismatch` alih-alih membandingkan string negara mentah sendiri."
              },
              "ip_state": {
                "type": "string",
                "nullable": true,
                "description": "Negara bagian atau wilayah hasil resolusi."
              },
              "ip_city": {
                "type": "string",
                "nullable": true,
                "description": "Kota hasil resolusi."
              },
              "latitude": {
                "type": "number",
                "nullable": true,
                "description": "Geolokasi jaringan perkiraan, bukan lokasi perangkat yang presisi."
              },
              "longitude": {
                "type": "number",
                "nullable": true,
                "description": "Geolokasi jaringan perkiraan, bukan lokasi perangkat yang presisi."
              },
              "isp": {
                "type": "string",
                "nullable": true,
                "description": "Penyedia layanan internet yang melayani alamat tersebut."
              },
              "organization": {
                "type": "string",
                "nullable": true,
                "description": "Organisasi yang memiliki blok alamat."
              },
              "is_vpn_or_tor": {
                "type": "boolean",
                "nullable": true,
                "description": "`true` jika alamat dikaitkan dengan infrastruktur VPN atau Tor."
              },
              "is_data_center": {
                "type": "boolean",
                "nullable": true,
                "description": "`true` jika alamat termasuk dalam jaringan hosting atau pusat data."
              },
              "time_zone": {
                "type": "string",
                "nullable": true,
                "description": "Zona waktu dari lokasi hasil resolusi."
              },
              "time_zone_offset": {
                "type": "string",
                "nullable": true,
                "description": "Offset UTC dari lokasi yang ditentukan."
              },
              "asn_number": {
                "type": "number",
                "nullable": true,
                "description": "Nomor sistem otonom."
              },
              "asn_organization": {
                "type": "string",
                "nullable": true,
                "description": "Organisasi yang mengoperasikan sistem otonom."
              },
              "connection_type": {
                "type": "string",
                "nullable": true,
                "description": "Klasifikasi koneksi (misalnya, `cellular`, `hosting`)."
              },
              "carrier": {
                "type": "string",
                "nullable": true,
                "description": "Operator seluler ketika alamat berada di jaringan seluler."
              },
              "proxy_type": {
                "type": "string",
                "nullable": true,
                "description": "Klasifikasi proksi saat alamat berada di balik proksi."
              },
              "claimed_country": {
                "type": "string",
                "nullable": true,
                "description": "Salinan `claimed_country` yang Anda kirimkan."
              },
              "country_mismatch": {
                "type": "boolean",
                "nullable": true,
                "description": "`true` saat negara yang teridentifikasi berbeda dari `claimed_country`. `null` saat tidak ada data pengayaan atau tidak ada negara yang diklaim yang tersedia."
              },
              "threat": {
                "type": "object",
                "additionalProperties": true,
                "description": "Bukti ancaman jaringan bentuk bebas dari sumber pengayaan (misalnya, `is_proxy`, `is_tor`). Objek kosong jika tidak ada data pengayaan yang tersedia. Perlakukan sebagai detail diagnostik, bukan kontrak yang stabil."
              }
            }
          }
        }
      },
      "SocialFootprintPlatform": {
        "type": "object",
        "properties": {
          "platform": {
            "type": "string",
            "description": "Pengenal platform.",
            "example": "whatsapp"
          },
          "category": {
            "type": "string",
            "description": "Kategori platform, mis. MESSAGING, SOCIAL_MEDIA, ECOMMERCE, PROFESSIONAL, EMAIL_PROVIDER.",
            "example": "MESSAGING"
          },
          "scope": {
            "type": "string",
            "enum": [
              "global",
              "local"
            ],
            "description": "`global` untuk platform di seluruh dunia, `local` untuk platform khusus kawasan tertentu.",
            "example": "global"
          }
        }
      },
      "SocialFootprintCategorySummary": {
        "type": "object",
        "properties": {
          "registered": {
            "type": "integer",
            "nullable": true,
            "description": "Platform dalam kategori ini tempat pendaftaran dikonfirmasi.",
            "example": 2
          },
          "ratio": {
            "type": "number",
            "format": "float",
            "nullable": true,
            "description": "Porsi platform yang diperiksa dalam kategori tersebut yang memiliki registrasi, 0.0-1.0.",
            "example": 0.6667
          }
        }
      },
      "SocialFootprintProfile": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "nullable": true,
            "description": "Nama profil, jika platform menampilkannya."
          },
          "photo": {
            "type": "string",
            "nullable": true,
            "description": "URL foto profil, jika platform menampilkannya."
          },
          "about": {
            "type": "string",
            "nullable": true,
            "description": "Teks tentang/bio profil, jika platform menampilkannya."
          },
          "privacy_status": {
            "type": "string",
            "nullable": true,
            "enum": [
              "PUBLIC",
              "PRIVATE",
              null
            ],
            "description": "Visibilitas profil, jika platform menampilkannya."
          },
          "business_account": {
            "type": "boolean",
            "nullable": true,
            "description": "Apakah profil tersebut merupakan akun bisnis, jika platform menampilkannya."
          }
        }
      },
      "PhoneSocialFootprint": {
        "type": "object",
        "nullable": true,
        "description": "Jejak sosial dari nomor telepon: platform online tempat nomor tersebut terdaftar. Ada hanya jika `enable_social` diatur dan pemeriksaan selesai. Setiap hitungan dapat bernilai null jika tidak ada data yang dikembalikan untuknya. `profiles_registered: 0` berarti platform telah diperiksa dan nomor telepon tidak ditemukan di platform mana pun - respons yang valid, dapat ditagih, dan merupakan sinyal identitas sintetis yang umum.",
        "properties": {
          "profiles_registered": {
            "type": "integer",
            "nullable": true,
            "description": "Platform tempat nomor telepon dikonfirmasi terdaftar.",
            "example": 5
          },
          "profiles_checked": {
            "type": "integer",
            "nullable": true,
            "description": "Platform yang dievaluasi untuk pendaftaran.",
            "example": 14
          },
          "names_found": {
            "type": "integer",
            "nullable": true,
            "description": "Platform yang mengembalikan nama terkait.",
            "example": 0
          },
          "photos_found": {
            "type": "integer",
            "nullable": true,
            "description": "Platform yang mengembalikan foto profil.",
            "example": 0
          },
          "communication_breadth": {
            "type": "integer",
            "nullable": true,
            "description": "Platform komunikasi yang keberadaannya terdeteksi.",
            "example": 2
          },
          "digital_footprint_diversity": {
            "type": "integer",
            "nullable": true,
            "description": "Kategori platform unik dengan keberadaan yang terdeteksi.",
            "example": 5
          },
          "digital_sophistication_index": {
            "type": "integer",
            "nullable": true,
            "description": "Indikator kematangan digital komposit, 0-10.",
            "example": 5
          },
          "engagement_depth_index": {
            "type": "integer",
            "nullable": true,
            "description": "Indikator kekayaan profil, 0-10.",
            "example": 3
          },
          "subscription_affordability_index": {
            "type": "integer",
            "nullable": true,
            "description": "Bauran platform gratis vs berbayar, 0-10.",
            "example": 2
          },
          "free_platforms": {
            "type": "integer",
            "nullable": true,
            "description": "Pendaftaran pada platform gratis.",
            "example": 4
          },
          "full_paid_platforms": {
            "type": "integer",
            "nullable": true,
            "description": "Pendaftaran pada platform berbayar penuh.",
            "example": 0
          },
          "partial_paid_platforms": {
            "type": "integer",
            "nullable": true,
            "description": "Pendaftaran pada platform freemium.",
            "example": 1
          },
          "whatsapp_profile_completeness": {
            "type": "string",
            "nullable": true,
            "enum": [
              "Basic",
              "Partial",
              "Complete",
              "Not Present",
              null
            ],
            "description": "Kelengkapan profil WhatsApp. Hanya untuk telepon; null untuk email.",
            "example": "Partial"
          },
          "registered_platforms": {
            "type": "array",
            "description": "Platform tempat pendaftaran dikonfirmasi.",
            "items": {
              "$ref": "#/components/schemas/SocialFootprintPlatform"
            }
          },
          "not_registered_platforms": {
            "type": "array",
            "description": "Platform yang diperiksa dengan hasil negatif.",
            "items": {
              "$ref": "#/components/schemas/SocialFootprintPlatform"
            }
          },
          "categories": {
            "type": "object",
            "description": "Jumlah dan rasio terdaftar per kategori platform.",
            "additionalProperties": {
              "$ref": "#/components/schemas/SocialFootprintCategorySummary"
            }
          },
          "profiles": {
            "type": "object",
            "description": "Detail profil per platform, dikunci berdasarkan platform, jika platform menyediakannya.",
            "additionalProperties": {
              "$ref": "#/components/schemas/SocialFootprintProfile"
            }
          }
        }
      },
      "EmailSocialFootprint": {
        "type": "object",
        "nullable": true,
        "description": "Jejak sosial dari alamat email: platform online tempat alamat tersebut terdaftar. Ada hanya jika `enable_social` diatur dan pemeriksaan selesai. Setiap hitungan dapat bernilai null jika tidak ada data yang dikembalikan untuknya. `profiles_registered: 0` berarti platform telah diperiksa dan alamat email tidak ditemukan di platform mana pun - respons yang valid, dapat ditagih, dan merupakan sinyal identitas sintetis yang umum.",
        "properties": {
          "profiles_registered": {
            "type": "integer",
            "nullable": true,
            "description": "Platform tempat alamat email dikonfirmasi terdaftar.",
            "example": 5
          },
          "profiles_checked": {
            "type": "integer",
            "nullable": true,
            "description": "Platform yang dievaluasi untuk pendaftaran.",
            "example": 14
          },
          "names_found": {
            "type": "integer",
            "nullable": true,
            "description": "Platform yang mengembalikan nama terkait.",
            "example": 0
          },
          "photos_found": {
            "type": "integer",
            "nullable": true,
            "description": "Platform yang mengembalikan foto profil.",
            "example": 0
          },
          "communication_breadth": {
            "type": "integer",
            "nullable": true,
            "description": "Platform komunikasi yang keberadaannya terdeteksi.",
            "example": 2
          },
          "digital_footprint_diversity": {
            "type": "integer",
            "nullable": true,
            "description": "Kategori platform unik dengan keberadaan yang terdeteksi.",
            "example": 5
          },
          "digital_sophistication_index": {
            "type": "integer",
            "nullable": true,
            "description": "Indikator kematangan digital komposit, 0-10.",
            "example": 5
          },
          "engagement_depth_index": {
            "type": "integer",
            "nullable": true,
            "description": "Indikator kekayaan profil, 0-10.",
            "example": 3
          },
          "subscription_affordability_index": {
            "type": "integer",
            "nullable": true,
            "description": "Bauran platform gratis vs berbayar, 0-10.",
            "example": 2
          },
          "free_platforms": {
            "type": "integer",
            "nullable": true,
            "description": "Pendaftaran pada platform gratis.",
            "example": 4
          },
          "full_paid_platforms": {
            "type": "integer",
            "nullable": true,
            "description": "Pendaftaran pada platform berbayar penuh.",
            "example": 0
          },
          "partial_paid_platforms": {
            "type": "integer",
            "nullable": true,
            "description": "Pendaftaran pada platform freemium.",
            "example": 1
          },
          "whatsapp_profile_completeness": {
            "type": "string",
            "nullable": true,
            "enum": [
              "Basic",
              "Partial",
              "Complete",
              "Not Present",
              null
            ],
            "description": "Kelengkapan profil WhatsApp. Hanya untuk telepon; null untuk email.",
            "example": "Partial"
          },
          "registered_platforms": {
            "type": "array",
            "description": "Platform tempat pendaftaran dikonfirmasi.",
            "items": {
              "$ref": "#/components/schemas/SocialFootprintPlatform"
            }
          },
          "not_registered_platforms": {
            "type": "array",
            "description": "Platform yang diperiksa dengan hasil negatif.",
            "items": {
              "$ref": "#/components/schemas/SocialFootprintPlatform"
            }
          },
          "categories": {
            "type": "object",
            "description": "Jumlah dan rasio terdaftar per kategori platform.",
            "additionalProperties": {
              "$ref": "#/components/schemas/SocialFootprintCategorySummary"
            }
          },
          "profiles": {
            "type": "object",
            "description": "Detail profil per platform, dikunci berdasarkan platform, jika platform menyediakannya.",
            "additionalProperties": {
              "$ref": "#/components/schemas/SocialFootprintProfile"
            }
          }
        }
      },
      "KYBRegistryAddress": {
        "type": "object",
        "description": "Alamat yang dinyatakan oleh registri, dalam bentuk yang sama untuk setiap negara dan sumber registri. Setiap kunci selalu ada; bagian yang tidak dipublikasikan oleh registri bernilai null.",
        "properties": {
          "type": {
            "type": "string",
            "nullable": true,
            "description": "Jenis alamat dalam huruf kecil: `registered` untuk kantor terdaftar; jenis lain sebagaimana dinamai oleh registri (misalnya `postal`, `office`). `null` jika registri tidak menyebutkan jenis alamat tersebut."
          },
          "address": {
            "type": "string",
            "description": "Alamat lengkap dalam satu baris. Selalu ada pada setiap alamat."
          },
          "street": {
            "type": "string",
            "nullable": true,
            "description": "Jalan dan nomor."
          },
          "city": {
            "type": "string",
            "nullable": true,
            "description": "Kota atau lokalitas."
          },
          "postal_code": {
            "type": "string",
            "nullable": true,
            "description": "Kode pos."
          },
          "region": {
            "type": "string",
            "nullable": true,
            "description": "Wilayah, negara bagian, atau provinsi."
          },
          "country_code": {
            "type": "string",
            "nullable": true,
            "description": "Kode negara ISO 3166-1 alpha-2."
          },
          "description": {
            "type": "string",
            "nullable": true,
            "description": "Label milik registri sendiri untuk alamat tersebut, jika menyediakannya."
          }
        },
        "required": [
          "type",
          "address",
          "street",
          "city",
          "postal_code",
          "region",
          "country_code",
          "description"
        ]
      },
      "KYBRegistryIndustry": {
        "type": "object",
        "description": "Aktivitas yang diklasifikasikan oleh registri untuk perusahaan tersebut, dalam bentuk yang sama untuk setiap negara dan sumber registri.",
        "properties": {
          "code": {
            "type": "string",
            "nullable": true,
            "description": "Kode aktivitas sebagaimana yang tercetak pada registri (misalnya `73110`)."
          },
          "description": {
            "type": "string",
            "nullable": true,
            "description": "Label aktivitas, jika registri menerbitkannya."
          },
          "scheme": {
            "type": "string",
            "nullable": true,
            "description": "Sistem klasifikasi, satu nama per sistem dari sumber mana pun yang melaporkannya: `UK SIC 2007`, `US SIC`, `NACE Rev. 2`, `NACE Rev. 2.1`, `NAF Rev. 2`, `CNAE`, `SBI`, `NOGA 2008`, `CAE Rev. 4`, `Canada SIC 1977`; sistem nasional lainnya tetap menggunakan nama dari registri itu sendiri. Bernilai null jika registri tidak mencantumkan nama sistem."
          },
          "is_primary": {
            "type": "boolean",
            "description": "True untuk aktivitas utama perusahaan. Tepat satu entri bersifat primer saat daftar tidak kosong."
          }
        },
        "required": [
          "code",
          "description",
          "scheme",
          "is_primary"
        ]
      },
      "KYBRegistryShareholding": {
        "type": "object",
        "nullable": true,
        "description": "Apa yang dimiliki seorang pemilik, dalam format yang sama untuk setiap negara dan sumber registri. Null jika registri tidak menyatakan adanya kepemilikan. Rentang persentase (misalnya 25-50% pada PSC Inggris) bukan merupakan bagian kepemilikan: `percentage` bernilai null dan rentang tersebut tetap berada di `ownership_min_shares` / `ownership_max_shares`.",
        "properties": {
          "share_class": {
            "type": "string",
            "nullable": true,
            "description": "Kelas atau jenis saham sebagaimana dinamai oleh registri."
          },
          "number_of_shares": {
            "type": "number",
            "nullable": true,
            "description": "Jumlah saham yang dimiliki."
          },
          "currency": {
            "type": "string",
            "nullable": true,
            "description": "Mata uang ISO 4217 dari nilai di bawah."
          },
          "nominal_value": {
            "type": "number",
            "nullable": true,
            "description": "Nilai nominal per saham."
          },
          "total_value": {
            "type": "number",
            "nullable": true,
            "description": "Nilai total kepemilikan."
          },
          "percentage": {
            "type": "number",
            "nullable": true,
            "description": "Porsi kepemilikan persis dalam persen, hingga empat tempat desimal."
          }
        },
        "required": [
          "share_class",
          "number_of_shares",
          "currency",
          "nominal_value",
          "total_value",
          "percentage"
        ]
      },
      "KYBRegistryOwnership": {
        "type": "object",
        "description": "Hasil dari tingkat kepemilikan (Pemegang Saham / UBO), dalam format yang sama untuk setiap negara dan sumber registri.",
        "properties": {
          "status": {
            "type": "string",
            "nullable": true,
            "enum": [
              "not_requested",
              "pending",
              "delivered",
              "not_held",
              "unavailable",
              null
            ],
            "description": "`delivered` saat registri memublikasikan kepemilikan; `not_held` saat registri kepemilikan merespons dan sama sekali tidak mencantumkan perusahaan tersebut (lihat `unavailable_reason`); `unavailable` saat registri tidak menyajikan data kepemilikan karena alasan lain apa pun (lihat `unavailable_reason`); `pending` saat registri masih mengambilnya; `not_requested` untuk tingkat Basic."
          },
          "tier_requested": {
            "type": "string",
            "nullable": true,
            "enum": [
              "basic",
              "shareholders",
              "ubo",
              null
            ],
            "description": "Tingkat yang dipesan oleh alur kerja."
          },
          "tier_delivered": {
            "type": "string",
            "nullable": true,
            "enum": [
              "basic",
              "shareholders",
              "ubo",
              null
            ],
            "description": "Tingkat yang dikirimkan oleh registri (dan yang ditagihkan). Permintaan UBO yang dijawab hanya dengan pemegang saham langsung adalah `shareholders`."
          },
          "unavailable_reason": {
            "type": "string",
            "nullable": true,
            "enum": [
              "no_owners_on_record",
              "no_natural_person_owner",
              "ownership_section_unavailable",
              "company_not_found",
              "ambiguous_company_match",
              "missing_registration_number",
              "entity_type_not_covered",
              "provider_unavailable",
              "other",
              null
            ],
            "description": "Alasan tingkat kepemilikan yang diminta tidak diberikan. Bernilai null kecuali `status` adalah `unavailable` atau `pending`."
          },
          "direct_ownership_complete": {
            "type": "boolean",
            "nullable": true,
            "description": "True saat kepemilikan saham yang dinyatakan pemegang saham langsung berjumlah 100% (dalam batas pembulatan satu poin persentase); false jika tidak; null jika kepemilikan tidak dikirimkan atau besaran saham tidak dinyatakan."
          },
          "unresolved": {
            "type": "array",
            "description": "Bagian dari rantai kepemilikan yang tidak dapat diselesaikan oleh registri, misalnya tidak ada struktur grup yang tercatat di atas pemilik langsung.",
            "items": {
              "type": "object",
              "properties": {
                "reason": {
                  "type": "string"
                },
                "section": {
                  "type": "string",
                  "nullable": true
                }
              }
            }
          }
        },
        "required": [
          "status",
          "tier_requested",
          "tier_delivered",
          "unavailable_reason",
          "direct_ownership_complete",
          "unresolved"
        ]
      },
      "KYBRegistryData": {
        "type": "object",
        "nullable": true,
        "description": "Detail registri yang dinormalisasi Didit untuk perusahaan: hasil kepemilikan (`ownership_error`, `section_errors`, `ubo_resolution`, `lite_enrichment`), koreksi yang dilakukan dengan update-data, dan fakta registri yang tidak memiliki kolom tersendiri. Kolom ini tidak pernah memuat catatan asli dari sumber registri. Setiap kunci bersifat opsional dan hanya ada jika perusahaan memiliki nilai untuk kunci tersebut; kunci baru dapat ditambahkan. Baca kolom kanonikal (`addresses`, `industries`, `ownership`, `beneficial_owners[].shareholding`) untuk hal apa pun yang dicakupnya.",
        "properties": {
          "company_name": {
            "type": "string",
            "description": "Nama perusahaan sebagaimana dikoreksi di konsol."
          },
          "registration_number": {
            "type": "string",
            "description": "Nomor registrasi sebagaimana tercantum di registri atau koreksi konsol."
          },
          "country_code": {
            "type": "string",
            "description": "Negara registrasi sebagaimana dinyatakan oleh registri atau koreksi konsol."
          },
          "region": {
            "type": "string",
            "description": "Wilayah atau negara bagian dari registrasi."
          },
          "incorporation_date": {
            "type": "string",
            "description": "Tanggal pendirian (ISO 8601)."
          },
          "registration_date": {
            "type": "string",
            "description": "Tanggal pendaftaran (ISO 8601) jika registri mencantumkan tanggal yang berbeda dari tanggal pendirian."
          },
          "dissolution_date": {
            "type": "string",
            "description": "Tanggal pembubaran (ISO 8601) jika registri menyediakannya."
          },
          "tax_number": {
            "type": "string",
            "description": "ID pajak."
          },
          "vat_number": {
            "type": "string",
            "description": "Nomor PPN."
          },
          "legal_address": {
            "type": "string",
            "description": "Alamat resmi seperti yang dikoreksi di konsol."
          },
          "registered_address": {
            "type": "string",
            "description": "Alamat terdaftar sesuai yang tercantum di registri."
          },
          "company_type": {
            "type": "string",
            "description": "Bentuk hukum."
          },
          "registry_status": {
            "type": "string",
            "description": "Status perusahaan di registri."
          },
          "verification_status": {
            "type": "string",
            "description": "Status verifikasi."
          },
          "alternative_names": {
            "type": "string",
            "description": "Nama lain yang digunakan atau pernah digunakan perusahaan untuk menjalankan bisnis."
          },
          "nature_of_business": {
            "type": "string",
            "description": "Deskripsi aktivitas."
          },
          "registered_capital": {
            "type": "string",
            "description": "Modal terdaftar seperti yang tercetak."
          },
          "registered_capital_amount": {
            "type": "string",
            "description": "Jumlah modal terdaftar, sebagai string desimal."
          },
          "registered_capital_currency": {
            "type": "string",
            "description": "Mata uang modal terdaftar (ISO 4217)."
          },
          "website": {
            "type": "string",
            "description": "Situs web."
          },
          "email": {
            "type": "string",
            "description": "Email kontak."
          },
          "phone": {
            "type": "string",
            "description": "Telepon kontak."
          },
          "legal_entity_identifier": {
            "type": "string",
            "description": "Legal Entity Identifier (LEI)."
          },
          "location_of_registration": {
            "type": "string",
            "description": "Tempat registrasi."
          },
          "control_scheme": {
            "type": "string",
            "description": "Skema tata kelola saat registri menampilkannya."
          },
          "ownership_error": {
            "type": "string",
            "enum": [
              "no_owners_on_record",
              "no_natural_person_owner",
              "ownership_section_unavailable",
              "company_not_found",
              "ambiguous_company_match",
              "missing_registration_number",
              "entity_type_not_covered",
              "provider_unavailable",
              "other"
            ],
            "description": "Alasan tingkat kepemilikan yang diminta tidak diberikan, dalam kode yang sama dengan `ownership.unavailable_reason`. `no_owners_on_record` (registri merespons dan tidak menyebutkan pemilik) dan `ownership_section_unavailable` (registri tidak mengembalikan bagian kepemilikan) merupakan temuan yang berbeda."
          },
          "section_errors": {
            "type": "object",
            "description": "Bagian yang tidak dikembalikan oleh registri, dengan kunci berdasarkan bagian (`officers`, `shareholders`, `group_structure`). Bagian yang tercantum di sini tidak pernah dikirimkan: daftar kosong di sampingnya tidak menunjukkan apa pun tentang perusahaan.",
            "additionalProperties": {
              "$ref": "#/components/schemas/KYBRegistrySectionError"
            }
          },
          "ubo_resolution": {
            "$ref": "#/components/schemas/KYBRegistryUboResolution"
          },
          "lite_enrichment": {
            "$ref": "#/components/schemas/KYBRegistryLiteEnrichment"
          },
          "registry_metadata": {
            "type": "object",
            "additionalProperties": {
              "oneOf": [
                {
                  "type": "string"
                },
                {
                  "type": "number"
                },
                {
                  "type": "boolean"
                }
              ]
            },
            "description": "Kolom milik registri sendiri untuk perusahaan, dengan kunci sesuai penamaan registri, sebagai nilai biasa (rekaman lama). Hanya kolom yang ditinjau sebagai fakta registri yang disertakan."
          },
          "registry_sources": {
            "type": "array",
            "description": "Registri resmi tempat catatan dibaca (catatan lama). Sumber lain tidak disebutkan namanya.",
            "items": {
              "$ref": "#/components/schemas/KYBRegistrySource"
            }
          },
          "previous_names": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Nama yang pernah digunakan perusahaan saat terdaftar sebelumnya (catatan historis)."
          },
          "parent_companies": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Perusahaan induk yang dicantumkan oleh registri (catatan lama)."
          },
          "documents_available": {
            "type": "integer",
            "description": "Berapa banyak pengajuan yang disediakan registri untuk perusahaan tersebut (catatan terdahulu)."
          }
        }
      },
      "KYBRegistryGroupCompany": {
        "type": "object",
        "description": "Perusahaan dari grup korporasi, berdasarkan identitas registrinya.",
        "properties": {
          "name": {
            "type": "string",
            "nullable": true,
            "description": "Nama perusahaan."
          },
          "country_code": {
            "type": "string",
            "nullable": true,
            "description": "Negara registrasi."
          },
          "registration_number": {
            "type": "string",
            "nullable": true,
            "description": "Nomor registrasi."
          }
        },
        "required": [
          "name",
          "country_code",
          "registration_number"
        ]
      },
      "KYBRegistryUboResolution": {
        "type": "object",
        "description": "Bagaimana tingkat UBO menelusuri rantai kepemilikan di atas perusahaan tersebut.",
        "properties": {
          "parent_chain": {
            "type": "array",
            "description": "Induk perusahaan dari induk utama hingga perusahaan.",
            "items": {
              "$ref": "#/components/schemas/KYBRegistryGroupCompany"
            }
          },
          "subsidiaries": {
            "type": "array",
            "description": "Perusahaan langsung di bawah perusahaan tersebut dalam grup perusahaannya.",
            "items": {
              "$ref": "#/components/schemas/KYBRegistryGroupCompany"
            }
          },
          "unresolved": {
            "type": "array",
            "description": "Bagian dari rantai yang tidak dapat diselesaikan oleh registri (entri yang sama dengan `ownership.unresolved`).",
            "items": {
              "type": "object",
              "properties": {
                "reason": {
                  "type": "string",
                  "description": "Alasan, misalnya `no_group_structure_on_record`, `selected_company_not_in_group_structure`, atau `section_error`."
                },
                "section": {
                  "type": "string",
                  "nullable": true,
                  "description": "Bagian yang terkait, misalnya `group_structure`."
                }
              },
              "required": [
                "reason",
                "section"
              ]
            }
          }
        },
        "required": [
          "parent_chain",
          "subsidiaries",
          "unresolved"
        ]
      },
      "KYBRegistrySectionError": {
        "type": "object",
        "description": "Bagian yang tidak dikembalikan oleh registri.",
        "properties": {
          "status_code": {
            "type": "integer",
            "nullable": true,
            "description": "Status jawaban registri untuk bagian tersebut."
          }
        },
        "required": [
          "status_code"
        ]
      },
      "KYBRegistryLiteEnrichment": {
        "type": "object",
        "description": "Kolom profil Lite kosong yang diisi oleh sumber registri negara tersebut yang lain. Sumber tersebut tidak disebutkan namanya.",
        "properties": {
          "fields": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Kolom perusahaan yang telah diisi."
          },
          "people_added": {
            "type": "integer",
            "description": "Berapa banyak pejabat atau pemilik yang ditambahkan."
          }
        },
        "required": [
          "fields",
          "people_added"
        ]
      },
      "KYBRegistrySource": {
        "type": "object",
        "description": "Registri resmi tempat rekaman dibaca. Hanya registri resmi pemerintah, regulator, dan sistem pengidentifikasi resmi yang disebutkan; sumber lainnya diabaikan.",
        "properties": {
          "name": {
            "type": "string",
            "description": "Nama registri, misalnya `UK Companies House`."
          },
          "source_type": {
            "type": "string",
            "enum": [
              "official"
            ],
            "description": "Selalu `official`."
          }
        },
        "required": [
          "name",
          "source_type"
        ]
      },
      "KYBOwnershipStructure": {
        "type": "object",
        "nullable": true,
        "description": "Cap table yang dibuktikan oleh registri, sesuai keadaannya saat tingkat kepemilikan dikirimkan: `shareholders` langsung dan `beneficial_owners`. Null jika registri tidak membuktikan kepemilikan apa pun. Ini tidak pernah membawa baris milik sumber registri itu sendiri; baca `company.beneficial_owners` dan `company.ownership` untuk catatan saat ini.",
        "properties": {
          "shareholders": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/KYBOwnershipStructureOwner"
            }
          },
          "beneficial_owners": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/KYBOwnershipStructureOwner"
            }
          }
        },
        "required": [
          "shareholders",
          "beneficial_owners"
        ]
      },
      "KYBOwnershipStructureOwner": {
        "type": "object",
        "description": "Satu pemilik dari snapshot kepemilikan: identitas registri dan porsi kepemilikan yang sama dengan `company.beneficial_owners[]`, serta `shareholding` kanonisnya.",
        "properties": {
          "name": {
            "type": "string",
            "nullable": true,
            "description": "Nama pemilik sebagaimana tercantum di registri."
          },
          "first_name": {
            "type": "string",
            "nullable": true,
            "description": "Nama depan, untuk perorangan, jika registri menyatakannya."
          },
          "last_name": {
            "type": "string",
            "nullable": true,
            "description": "Nama keluarga, untuk perorangan, jika dinyatakan oleh registri."
          },
          "date_of_birth": {
            "type": "string",
            "nullable": true,
            "description": "Tanggal lahir (ISO 8601) ketika registri mempublikasikannya."
          },
          "country_of_birth": {
            "type": "string",
            "nullable": true,
            "description": "Negara kelahiran saat registri mempublikasikannya."
          },
          "company_name": {
            "type": "string",
            "nullable": true,
            "description": "Nama perusahaan, untuk pemilik korporat."
          },
          "registration_number": {
            "type": "string",
            "nullable": true,
            "description": "Nomor registrasi, untuk pemilik korporat."
          },
          "entity_type": {
            "type": "string",
            "nullable": true,
            "enum": [
              "person",
              "company",
              null
            ],
            "description": "Apakah pemiliknya adalah perorangan atau perusahaan."
          },
          "nationality": {
            "type": "string",
            "nullable": true,
            "description": "Kewarganegaraan saat registri menyatakannya."
          },
          "designation": {
            "type": "string",
            "nullable": true,
            "description": "Gelar atau peran pemilik sebagaimana tercantum dalam registri."
          },
          "roles": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "`shareholder` untuk pemegang saham langsung, `ubo` untuk pemilik manfaat."
          },
          "ownership_min_shares": {
            "type": "string",
            "nullable": true,
            "description": "Batas bawah porsi kepemilikan, dalam persen (sama dengan batas atas untuk porsi kepemilikan yang pasti)."
          },
          "ownership_max_shares": {
            "type": "string",
            "nullable": true,
            "description": "Batas atas kepemilikan, dalam persen."
          },
          "voting_min_shares": {
            "type": "string",
            "nullable": true,
            "description": "Batas bawah hak suara, dalam persen."
          },
          "voting_max_shares": {
            "type": "string",
            "nullable": true,
            "description": "Batas atas hak suara, dalam persen."
          },
          "appointment_date": {
            "type": "string",
            "nullable": true,
            "description": "Tanggal kepemilikan atau pengangkatan dimulai (ISO 8601)."
          },
          "is_active": {
            "type": "boolean",
            "nullable": true,
            "description": "False untuk mantan pemilik."
          },
          "shareholding": {
            "$ref": "#/components/schemas/KYBRegistryShareholding"
          }
        },
        "required": [
          "name",
          "first_name",
          "last_name",
          "date_of_birth",
          "country_of_birth",
          "company_name",
          "registration_number",
          "entity_type",
          "nationality",
          "designation",
          "roles",
          "ownership_min_shares",
          "ownership_max_shares",
          "voting_min_shares",
          "voting_max_shares",
          "appointment_date",
          "is_active",
          "shareholding"
        ]
      },
      "DigitalIdWalletApiWalletVerificationError": {
        "type": "object",
        "properties": {
          "error": {
            "type": "string",
            "description": "Kode stabil yang dapat dibaca mesin, mis. wallet_unavailable."
          },
          "detail": {
            "type": "string"
          }
        },
        "required": [
          "detail",
          "error"
        ]
      },
      "DigitalIdWalletApiWalletVerificationStartForbidden": {
        "oneOf": [
          {
            "$ref": "#/components/schemas/DigitalIdWalletApiClientCredentialsForbiddenErrorMessage"
          },
          {
            "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
          }
        ]
      },
      "DigitalIdWalletApiClientCredentialsForbiddenErrorMessage": {
        "type": "object",
        "properties": {
          "detail": {
            "type": "string",
            "default": "Forbidden - User doesn't have permission"
          }
        }
      },
      "DigitalIdWalletApiWalletVerificationStartBadRequest": {
        "oneOf": [
          {
            "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationError"
          },
          {
            "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationFieldErrors"
          }
        ]
      },
      "DigitalIdWalletApiWalletVerificationFieldErrors": {
        "type": "object",
        "description": "Kesalahan validasi permintaan: setiap kolom yang ditolak beserta pesannya.",
        "additionalProperties": {
          "type": "array",
          "items": {
            "type": "string"
          }
        }
      },
      "DigitalIdWalletApiWalletVerificationResponse": {
        "type": "object",
        "description": "Satu verifikasi dompet mandiri, sebagaimana setiap endpoint dompet meresponsnya.",
        "properties": {
          "request_id": {
            "type": "string",
            "format": "uuid"
          },
          "wallet_verification": {
            "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationResult"
          },
          "vendor_data": {
            "type": "string",
            "nullable": true
          },
          "metadata": {
            "type": "object",
            "additionalProperties": {},
            "nullable": true,
            "description": "Objek metadata yang dikirim saat mulai, atau null."
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "created_at",
          "metadata",
          "request_id",
          "vendor_data",
          "wallet_verification"
        ]
      },
      "DigitalIdWalletApiWalletVerificationResult": {
        "type": "object",
        "properties": {
          "wallet": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DigitalIdWalletApiWallet"
              }
            ],
            "readOnly": true
          },
          "country": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "description": "Belum Selesai saat tertunda, kemudian Disetujui (diverifikasi) atau Ditolak."
          },
          "outcome": {
            "$ref": "#/components/schemas/DigitalIdWalletApiWalletVerificationResultOutcomeEnum"
          },
          "error": {
            "type": "string",
            "nullable": true,
            "readOnly": true
          },
          "interaction": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DigitalIdWalletApiInteractionEnum"
              }
            ],
            "readOnly": true
          },
          "simulated": {
            "type": "boolean",
            "readOnly": true
          },
          "expires_at": {
            "type": "string",
            "format": "date-time"
          },
          "next_action": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DigitalIdWalletApiWalletNextAction"
              }
            ],
            "nullable": true,
            "readOnly": true
          },
          "identity": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DigitalIdWalletApiWalletIdentity"
              }
            ],
            "nullable": true,
            "readOnly": true
          },
          "attributes": {
            "type": "object",
            "additionalProperties": {},
            "nullable": true,
            "readOnly": true
          },
          "level_of_assurance": {
            "type": "string",
            "nullable": true
          },
          "verified_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "signature_valid": {
            "type": "boolean",
            "nullable": true,
            "description": "True setelah tanda tangan kredensial diverifikasi; null untuk kredensial simulasi."
          },
          "credential_type": {
            "type": "string",
            "nullable": true
          }
        },
        "required": [
          "attributes",
          "country",
          "credential_type",
          "error",
          "expires_at",
          "identity",
          "interaction",
          "level_of_assurance",
          "next_action",
          "outcome",
          "signature_valid",
          "simulated",
          "status",
          "verified_at",
          "wallet"
        ]
      },
      "DigitalIdWalletApiWalletIdentity": {
        "type": "object",
        "properties": {
          "full_name": {
            "type": "string",
            "nullable": true
          },
          "first_name": {
            "type": "string",
            "nullable": true
          },
          "last_name": {
            "type": "string",
            "nullable": true
          },
          "date_of_birth": {
            "type": "string",
            "format": "date",
            "nullable": true
          },
          "nationality": {
            "type": "string",
            "nullable": true,
            "description": "Kewarganegaraan ISO3, hanya jika dompet menyatakannya (tidak pernah disimpulkan)."
          },
          "issuing_state": {
            "type": "string",
            "description": "Negara ISO3 yang skemanya menerbitkan identitas."
          }
        },
        "required": [
          "date_of_birth",
          "first_name",
          "full_name",
          "issuing_state",
          "last_name",
          "nationality"
        ]
      },
      "DigitalIdWalletApiWalletNextAction": {
        "type": "object",
        "properties": {
          "type": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DigitalIdWalletApiWalletNextActionTypeEnum"
              }
            ],
            "description": "redirect: arahkan peramban pengguna ke url. confirm_in_app: tampilkan verification_code kepada pengguna, yang memeriksa kecocokannya dengan kode di aplikasi dompet mereka dan mengonfirmasinya di sana; lalu lakukan polling. request_digital_credential: dalam interaksi pengguna pada origin tempat Anda memulai, minta ke dompet dengan digital_credentials.request, lalu kirimkan hasilnya ke POST .../verifications/{request_id}/response/.\n\n* `redirect` - redirect\n* `confirm_in_app` - confirm_in_app\n* `request_digital_credential` - request_digital_credential"
          },
          "url": {
            "type": "string",
            "format": "uri",
            "description": "khusus redirect: tempat pengguna masuk dengan dompet."
          },
          "digital_credentials": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DigitalIdWalletApiWalletDigitalCredentialsRequest"
              }
            ],
            "description": "khusus request_digital_credential: permintaan yang diserahkan ke dompet."
          },
          "verification_code": {
            "type": "string",
            "description": "hanya confirm_in_app: kode perbandingan 4 digit yang juga ditampilkan oleh aplikasi dompet."
          },
          "poll_interval_seconds": {
            "type": "integer",
            "description": "hanya confirm_in_app: seberapa sering memanggil POST .../verifications/{request_id}/poll/ untuk umpan balik cepat. Didit juga melakukan polling proses masuk yang tertunda di latar belakang, sehingga webhook melaporkan hasilnya meskipun Anda tidak melakukan polling."
          }
        },
        "required": [
          "type"
        ]
      },
      "DigitalIdWalletApiWalletNextActionTypeEnum": {
        "enum": [
          "redirect",
          "confirm_in_app",
          "request_digital_credential"
        ],
        "type": "string",
        "description": "* `redirect` - redirect\n* `confirm_in_app` - confirm_in_app\n* `request_digital_credential` - request_digital_credential"
      },
      "DigitalIdWalletApiInteractionEnum": {
        "enum": [
          "redirect",
          "in_app",
          "digital_credentials"
        ],
        "type": "string",
        "description": "* `redirect` - redirect\n* `in_app` - in_app\n* `digital_credentials` - digital_credentials"
      },
      "DigitalIdWalletApiWalletVerificationResultOutcomeEnum": {
        "enum": [
          "pending",
          "verified",
          "cancelled",
          "timeout",
          "failed"
        ],
        "type": "string",
        "description": "* `pending` - Menunggu\n* `verified` - Terverifikasi\n* `cancelled` - Dibatalkan oleh pengguna\n* `timeout` - Waktu habis\n* `failed` - Gagal"
      },
      "DigitalIdWalletApiWallet": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "ID katalog dompet, misalnya bankid_se."
          },
          "name": {
            "type": "string"
          },
          "issuing_authority": {
            "type": "string",
            "nullable": true
          }
        },
        "required": [
          "id",
          "issuing_authority",
          "name"
        ]
      },
      "DigitalIdWalletApiEudiWalletVerificationStartRequest": {
        "type": "object",
        "description": "Mulai verifikasi EUDI Wallet (AUT, BEL, BGR, HRV, CYP, CZE, DNK, EST, FIN, FRA, DEU, GRC, HUN, IRL, ITA, LVA, LTU, LUX, MLT, NLD, POL, PRT, ROU, SVK, SVN, ESP, SWE, ISL, LIE, NOR).",
        "properties": {
          "vendor_data": {
            "type": "string",
            "nullable": true,
            "description": "Referensi Anda sendiri untuk verifikasi ini (mis. ID pengguna Anda). Dikembalikan dalam hasil dan webhook."
          },
          "metadata": {
            "type": "object",
            "additionalProperties": {},
            "nullable": true,
            "description": "Objek JSON opsional yang disimpan bersama verifikasi dan dikembalikan dalam hasil serta webhook."
          },
          "sandbox_scenario": {
            "type": "string",
            "minLength": 1,
            "description": "Khusus aplikasi sandbox: hasil simulasi - 'wallet_cancelled', 'wallet_timeout', atau 'wallet_provider_error'; skenario lain (atau tanpa skenario) akan lolos verifikasi. Ditolak pada aplikasi di lingkungan produksi. Katalog lengkap tersedia di GET /v1/sandbox/scenarios/."
          },
          "country": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DigitalIdWalletApiEudiWalletVerificationStartCountryEnum"
              }
            ],
            "description": "Negara ISO 3166-1 alpha-3 dari identitas EUDI Wallet.\n\n* `AUT` - AUT\n* `BEL` - BEL\n* `BGR` - BGR\n* `HRV` - HRV\n* `CYP` - CYP\n* `CZE` - CZE\n* `DNK` - DNK\n* `EST` - EST\n* `FIN` - FIN\n* `FRA` - FRA\n* `DEU` - DEU\n* `GRC` - GRC\n* `HUN` - HUN\n* `IRL` - IRL\n* `ITA` - ITA\n* `LVA` - LVA\n* `LTU` - LTU\n* `LUX` - LUX\n* `MLT` - MLT\n* `NLD` - NLD\n* `POL` - POL\n* `PRT` - PRT\n* `ROU` - ROU\n* `SVK` - SVK\n* `SVN` - SVN\n* `ESP` - ESP\n* `SWE` - SWE\n* `ISL` - ISL\n* `LIE` - LIE\n* `NOR` - NOR"
          },
          "return_url": {
            "type": "string",
            "format": "uri",
            "minLength": 1,
            "description": "URL https tempat peramban pengguna kembali setelah dompet, dengan request_id dan result ditambahkan. Host-nya harus terdaftar di allowed_return_hosts aplikasi (atau merupakan domain White Label miliknya). Jangan pernah memercayai result secara mandiri: baca hasilnya dengan GET .../verifications/{request_id}/ atau webhook.",
            "maxLength": 2048
          },
          "device": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DigitalIdWalletApiDeviceEnum"
              }
            ],
            "default": "same_device",
            "description": "same_device saat pengguna masuk di perangkat yang menampilkan halaman Anda, cross_device saat mereka menggunakan perangkat lain (misalnya kode QR BankID).\n\n* `same_device` - same_device\n* `cross_device` - cross_device"
          }
        },
        "required": [
          "country",
          "return_url"
        ]
      },
      "DigitalIdWalletApiDeviceEnum": {
        "enum": [
          "same_device",
          "cross_device"
        ],
        "type": "string",
        "description": "* `same_device` - same_device\n* `cross_device` - cross_device"
      },
      "DigitalIdWalletApiEudiWalletVerificationStartCountryEnum": {
        "enum": [
          "AUT",
          "BEL",
          "BGR",
          "HRV",
          "CYP",
          "CZE",
          "DNK",
          "EST",
          "FIN",
          "FRA",
          "DEU",
          "GRC",
          "HUN",
          "IRL",
          "ITA",
          "LVA",
          "LTU",
          "LUX",
          "MLT",
          "NLD",
          "POL",
          "PRT",
          "ROU",
          "SVK",
          "SVN",
          "ESP",
          "SWE",
          "ISL",
          "LIE",
          "NOR"
        ],
        "type": "string",
        "description": "* `AUT` - AUT\n* `BEL` - BEL\n* `BGR` - BGR\n* `HRV` - HRV\n* `CYP` - CYP\n* `CZE` - CZE\n* `DNK` - DNK\n* `EST` - EST\n* `FIN` - FIN\n* `FRA` - FRA\n* `DEU` - DEU\n* `GRC` - GRC\n* `HUN` - HUN\n* `IRL` - IRL\n* `ITA` - ITA\n* `LVA` - LVA\n* `LTU` - LTU\n* `LUX` - LUX\n* `MLT` - MLT\n* `NLD` - NLD\n* `POL` - POL\n* `PRT` - PRT\n* `ROU` - ROU\n* `SVK` - SVK\n* `SVN` - SVN\n* `ESP` - ESP\n* `SWE` - SWE\n* `ISL` - ISL\n* `LIE` - LIE\n* `NOR` - NOR"
      },
      "DigitalIdWalletApiConnectidWalletVerificationStartRequest": {
        "type": "object",
        "description": "Mulai verifikasi ConnectID (AUS).",
        "properties": {
          "vendor_data": {
            "type": "string",
            "nullable": true,
            "description": "Referensi Anda sendiri untuk verifikasi ini (mis. ID pengguna Anda). Dikembalikan dalam hasil dan webhook."
          },
          "metadata": {
            "type": "object",
            "additionalProperties": {},
            "nullable": true,
            "description": "Objek JSON opsional yang disimpan bersama verifikasi dan dikembalikan dalam hasil serta webhook."
          },
          "sandbox_scenario": {
            "type": "string",
            "minLength": 1,
            "description": "Khusus aplikasi sandbox: hasil simulasi - 'wallet_cancelled', 'wallet_timeout', atau 'wallet_provider_error'; skenario lain (atau tanpa skenario) akan lolos verifikasi. Ditolak pada aplikasi di lingkungan produksi. Katalog lengkap tersedia di GET /v1/sandbox/scenarios/."
          },
          "country": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DigitalIdWalletApiConnectidWalletVerificationStartCountryEnum"
              }
            ],
            "default": "AUS",
            "description": "Negara ISO 3166-1 alpha-3 dari identitas ConnectID. Default-nya adalah AUS, satu-satunya negara yang dilayaninya.\n\n* `AUS` - AUS"
          },
          "authorisation_server_id": {
            "type": "string",
            "minLength": 1,
            "description": "ID server otorisasi yang dipilih dengan pemilih bank ConnectID. Sandbox default-nya adalah Mock Bank A.",
            "maxLength": 36
          },
          "return_url": {
            "type": "string",
            "format": "uri",
            "minLength": 1,
            "description": "URL https tempat peramban pengguna kembali setelah dompet, dengan request_id dan result ditambahkan. Host-nya harus terdaftar di allowed_return_hosts aplikasi (atau merupakan domain White Label miliknya). Jangan pernah memercayai result secara mandiri: baca hasilnya dengan GET .../verifications/{request_id}/ atau webhook.",
            "maxLength": 2048
          },
          "device": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DigitalIdWalletApiDeviceEnum"
              }
            ],
            "default": "same_device",
            "description": "same_device saat pengguna masuk di perangkat yang menampilkan halaman Anda, cross_device saat mereka menggunakan perangkat lain (misalnya kode QR BankID).\n\n* `same_device` - same_device\n* `cross_device` - cross_device"
          }
        },
        "required": [
          "return_url"
        ]
      },
      "DigitalIdWalletApiConnectidWalletVerificationStartCountryEnum": {
        "enum": [
          "AUS"
        ],
        "type": "string",
        "description": "* `AUS` - AUS"
      },
      "DigitalIdWalletApiAudkenniWalletVerificationStartRequest": {
        "type": "object",
        "description": "Mulai verifikasi Auðkenni (ISL).",
        "properties": {
          "vendor_data": {
            "type": "string",
            "nullable": true,
            "description": "Referensi Anda sendiri untuk verifikasi ini (mis. ID pengguna Anda). Dikembalikan dalam hasil dan webhook."
          },
          "metadata": {
            "type": "object",
            "additionalProperties": {},
            "nullable": true,
            "description": "Objek JSON opsional yang disimpan bersama verifikasi dan dikembalikan dalam hasil serta webhook."
          },
          "sandbox_scenario": {
            "type": "string",
            "minLength": 1,
            "description": "Khusus aplikasi sandbox: hasil simulasi - 'wallet_cancelled', 'wallet_timeout', atau 'wallet_provider_error'; skenario lain (atau tanpa skenario) akan lolos verifikasi. Ditolak pada aplikasi di lingkungan produksi. Katalog lengkap tersedia di GET /v1/sandbox/scenarios/."
          },
          "country": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DigitalIdWalletApiAudkenniWalletVerificationStartCountryEnum"
              }
            ],
            "default": "ISL",
            "description": "Negara ISO 3166-1 alpha-3 dari identitas Auðkenni. Default-nya adalah ISL, satu-satunya negara yang dilayaninya.\n\n* `ISL` - ISL"
          },
          "return_url": {
            "type": "string",
            "format": "uri",
            "minLength": 1,
            "description": "URL https tempat peramban pengguna kembali setelah dompet, dengan request_id dan result ditambahkan. Host-nya harus terdaftar di allowed_return_hosts aplikasi (atau merupakan domain White Label miliknya). Jangan pernah memercayai result secara mandiri: baca hasilnya dengan GET .../verifications/{request_id}/ atau webhook.",
            "maxLength": 2048
          },
          "device": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DigitalIdWalletApiDeviceEnum"
              }
            ],
            "default": "same_device",
            "description": "same_device saat pengguna masuk di perangkat yang menampilkan halaman Anda, cross_device saat mereka menggunakan perangkat lain (misalnya kode QR BankID).\n\n* `same_device` - same_device\n* `cross_device` - cross_device"
          }
        },
        "required": [
          "return_url"
        ]
      },
      "DigitalIdWalletApiAudkenniWalletVerificationStartCountryEnum": {
        "enum": [
          "ISL"
        ],
        "type": "string",
        "description": "* `ISL` - ISL"
      },
      "DigitalIdWalletApiFranceconnectWalletVerificationStartRequest": {
        "type": "object",
        "description": "Mulai verifikasi FranceConnect (FRA).",
        "properties": {
          "vendor_data": {
            "type": "string",
            "nullable": true,
            "description": "Referensi Anda sendiri untuk verifikasi ini (mis. ID pengguna Anda). Dikembalikan dalam hasil dan webhook."
          },
          "metadata": {
            "type": "object",
            "additionalProperties": {},
            "nullable": true,
            "description": "Objek JSON opsional yang disimpan bersama verifikasi dan dikembalikan dalam hasil serta webhook."
          },
          "sandbox_scenario": {
            "type": "string",
            "minLength": 1,
            "description": "Khusus aplikasi sandbox: hasil simulasi - 'wallet_cancelled', 'wallet_timeout', atau 'wallet_provider_error'; skenario lain (atau tanpa skenario) akan lolos verifikasi. Ditolak pada aplikasi di lingkungan produksi. Katalog lengkap tersedia di GET /v1/sandbox/scenarios/."
          },
          "country": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DigitalIdWalletApiFranceconnectWalletVerificationStartCountryEnum"
              }
            ],
            "default": "FRA",
            "description": "Negara ISO 3166-1 alpha-3 dari identitas FranceConnect. Default-nya adalah FRA, satu-satunya negara yang dilayaninya.\n\n* `FRA` - FRA"
          },
          "return_url": {
            "type": "string",
            "format": "uri",
            "minLength": 1,
            "description": "URL https tempat peramban pengguna kembali setelah dompet, dengan request_id dan result ditambahkan. Host-nya harus terdaftar di allowed_return_hosts aplikasi (atau merupakan domain White Label miliknya). Jangan pernah memercayai result secara mandiri: baca hasilnya dengan GET .../verifications/{request_id}/ atau webhook.",
            "maxLength": 2048
          },
          "device": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DigitalIdWalletApiDeviceEnum"
              }
            ],
            "default": "same_device",
            "description": "same_device saat pengguna masuk di perangkat yang menampilkan halaman Anda, cross_device saat mereka menggunakan perangkat lain (misalnya kode QR BankID).\n\n* `same_device` - same_device\n* `cross_device` - cross_device"
          }
        },
        "required": [
          "return_url"
        ]
      },
      "DigitalIdWalletApiFranceconnectWalletVerificationStartCountryEnum": {
        "enum": [
          "FRA"
        ],
        "type": "string",
        "description": "* `FRA` - FRA"
      },
      "DigitalIdWalletApiDiiaWalletVerificationStartRequest": {
        "type": "object",
        "description": "Mulai verifikasi Diia (UKR).",
        "properties": {
          "vendor_data": {
            "type": "string",
            "nullable": true,
            "description": "Referensi Anda sendiri untuk verifikasi ini (mis. ID pengguna Anda). Dikembalikan dalam hasil dan webhook."
          },
          "metadata": {
            "type": "object",
            "additionalProperties": {},
            "nullable": true,
            "description": "Objek JSON opsional yang disimpan bersama verifikasi dan dikembalikan dalam hasil serta webhook."
          },
          "sandbox_scenario": {
            "type": "string",
            "minLength": 1,
            "description": "Khusus aplikasi sandbox: hasil simulasi - 'wallet_cancelled', 'wallet_timeout', atau 'wallet_provider_error'; skenario lain (atau tanpa skenario) akan lolos verifikasi. Ditolak pada aplikasi di lingkungan produksi. Katalog lengkap tersedia di GET /v1/sandbox/scenarios/."
          },
          "country": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DigitalIdWalletApiDiiaWalletVerificationStartCountryEnum"
              }
            ],
            "default": "UKR",
            "description": "Negara ISO 3166-1 alpha-3 dari identitas Diia. Default-nya adalah UKR, satu-satunya negara yang dilayaninya.\n\n* `UKR` - UKR"
          },
          "return_url": {
            "type": "string",
            "format": "uri",
            "minLength": 1,
            "description": "URL https tempat peramban pengguna kembali setelah dompet, dengan request_id dan result ditambahkan. Host-nya harus terdaftar di allowed_return_hosts aplikasi (atau merupakan domain White Label miliknya). Jangan pernah memercayai result secara mandiri: baca hasilnya dengan GET .../verifications/{request_id}/ atau webhook.",
            "maxLength": 2048
          },
          "device": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DigitalIdWalletApiDeviceEnum"
              }
            ],
            "default": "same_device",
            "description": "same_device saat pengguna masuk di perangkat yang menampilkan halaman Anda, cross_device saat mereka menggunakan perangkat lain (misalnya kode QR BankID).\n\n* `same_device` - same_device\n* `cross_device` - cross_device"
          }
        },
        "required": [
          "return_url"
        ]
      },
      "DigitalIdWalletApiDiiaWalletVerificationStartCountryEnum": {
        "enum": [
          "UKR"
        ],
        "type": "string",
        "description": "* `UKR` - UKR"
      },
      "DigitalIdWalletApiMojeidWalletVerificationStartRequest": {
        "type": "object",
        "description": "Mulai verifikasi MojeID (CZE).",
        "properties": {
          "vendor_data": {
            "type": "string",
            "nullable": true,
            "description": "Referensi Anda sendiri untuk verifikasi ini (mis. ID pengguna Anda). Dikembalikan dalam hasil dan webhook."
          },
          "metadata": {
            "type": "object",
            "additionalProperties": {},
            "nullable": true,
            "description": "Objek JSON opsional yang disimpan bersama verifikasi dan dikembalikan dalam hasil serta webhook."
          },
          "sandbox_scenario": {
            "type": "string",
            "minLength": 1,
            "description": "Khusus aplikasi sandbox: hasil simulasi - 'wallet_cancelled', 'wallet_timeout', atau 'wallet_provider_error'; skenario lain (atau tanpa skenario) akan lolos verifikasi. Ditolak pada aplikasi di lingkungan produksi. Katalog lengkap tersedia di GET /v1/sandbox/scenarios/."
          },
          "country": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DigitalIdWalletApiCountryE2dEnum"
              }
            ],
            "default": "CZE",
            "description": "Negara ISO 3166-1 alpha-3 dari identitas MojeID. Secara default nilainya adalah CZE, satu-satunya negara yang dilayaninya.\n\n* `CZE` - CZE"
          },
          "return_url": {
            "type": "string",
            "format": "uri",
            "minLength": 1,
            "description": "URL https tempat peramban pengguna kembali setelah dompet, dengan request_id dan result ditambahkan. Host-nya harus terdaftar di allowed_return_hosts aplikasi (atau merupakan domain White Label miliknya). Jangan pernah memercayai result secara mandiri: baca hasilnya dengan GET .../verifications/{request_id}/ atau webhook.",
            "maxLength": 2048
          },
          "device": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DigitalIdWalletApiDeviceEnum"
              }
            ],
            "default": "same_device",
            "description": "same_device saat pengguna masuk di perangkat yang menampilkan halaman Anda, cross_device saat mereka menggunakan perangkat lain (misalnya kode QR BankID).\n\n* `same_device` - same_device\n* `cross_device` - cross_device"
          }
        },
        "required": [
          "return_url"
        ]
      },
      "DigitalIdWalletApiCountryE2dEnum": {
        "enum": [
          "CZE"
        ],
        "type": "string",
        "description": "* `CZE` - CZE"
      },
      "DigitalIdWalletApiBankidCzWalletVerificationStartRequest": {
        "type": "object",
        "description": "Mulai verifikasi Bank iD (CZE).",
        "properties": {
          "vendor_data": {
            "type": "string",
            "nullable": true,
            "description": "Referensi Anda sendiri untuk verifikasi ini (mis. ID pengguna Anda). Dikembalikan dalam hasil dan webhook."
          },
          "metadata": {
            "type": "object",
            "additionalProperties": {},
            "nullable": true,
            "description": "Objek JSON opsional yang disimpan bersama verifikasi dan dikembalikan dalam hasil serta webhook."
          },
          "sandbox_scenario": {
            "type": "string",
            "minLength": 1,
            "description": "Khusus aplikasi sandbox: hasil simulasi - 'wallet_cancelled', 'wallet_timeout', atau 'wallet_provider_error'; skenario lain (atau tanpa skenario) akan lolos verifikasi. Ditolak pada aplikasi di lingkungan produksi. Katalog lengkap tersedia di GET /v1/sandbox/scenarios/."
          },
          "country": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DigitalIdWalletApiCountryE2dEnum"
              }
            ],
            "default": "CZE",
            "description": "Negara ISO 3166-1 alpha-3 dari identitas Bank iD. Default-nya adalah CZE, satu-satunya negara yang dilayaninya.\n\n* `CZE` - CZE"
          },
          "return_url": {
            "type": "string",
            "format": "uri",
            "minLength": 1,
            "description": "URL https tempat peramban pengguna kembali setelah dompet, dengan request_id dan result ditambahkan. Host-nya harus terdaftar di allowed_return_hosts aplikasi (atau merupakan domain White Label miliknya). Jangan pernah memercayai result secara mandiri: baca hasilnya dengan GET .../verifications/{request_id}/ atau webhook.",
            "maxLength": 2048
          },
          "device": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DigitalIdWalletApiDeviceEnum"
              }
            ],
            "default": "same_device",
            "description": "same_device saat pengguna masuk di perangkat yang menampilkan halaman Anda, cross_device saat mereka menggunakan perangkat lain (misalnya kode QR BankID).\n\n* `same_device` - same_device\n* `cross_device` - cross_device"
          }
        },
        "required": [
          "return_url"
        ]
      },
      "DigitalIdWalletApiEparakstsMobileWalletVerificationStartRequest": {
        "type": "object",
        "description": "Mulai verifikasi eParaksts mobile (LVA).",
        "properties": {
          "vendor_data": {
            "type": "string",
            "nullable": true,
            "description": "Referensi Anda sendiri untuk verifikasi ini (mis. ID pengguna Anda). Dikembalikan dalam hasil dan webhook."
          },
          "metadata": {
            "type": "object",
            "additionalProperties": {},
            "nullable": true,
            "description": "Objek JSON opsional yang disimpan bersama verifikasi dan dikembalikan dalam hasil serta webhook."
          },
          "sandbox_scenario": {
            "type": "string",
            "minLength": 1,
            "description": "Khusus aplikasi sandbox: hasil simulasi - 'wallet_cancelled', 'wallet_timeout', atau 'wallet_provider_error'; skenario lain (atau tanpa skenario) akan lolos verifikasi. Ditolak pada aplikasi di lingkungan produksi. Katalog lengkap tersedia di GET /v1/sandbox/scenarios/."
          },
          "country": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DigitalIdWalletApiEparakstsMobileWalletVerificationStartCountryEnum"
              }
            ],
            "default": "LVA",
            "description": "Negara ISO 3166-1 alpha-3 dari identitas mobile eParaksts. Secara default bernilai LVA, satu-satunya negara yang dilayaninya.\n\n* `LVA` - LVA"
          },
          "return_url": {
            "type": "string",
            "format": "uri",
            "minLength": 1,
            "description": "URL https tempat peramban pengguna kembali setelah dompet, dengan request_id dan result ditambahkan. Host-nya harus terdaftar di allowed_return_hosts aplikasi (atau merupakan domain White Label miliknya). Jangan pernah memercayai result secara mandiri: baca hasilnya dengan GET .../verifications/{request_id}/ atau webhook.",
            "maxLength": 2048
          },
          "device": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DigitalIdWalletApiDeviceEnum"
              }
            ],
            "default": "same_device",
            "description": "same_device saat pengguna masuk di perangkat yang menampilkan halaman Anda, cross_device saat mereka menggunakan perangkat lain (misalnya kode QR BankID).\n\n* `same_device` - same_device\n* `cross_device` - cross_device"
          }
        },
        "required": [
          "return_url"
        ]
      },
      "DigitalIdWalletApiEparakstsMobileWalletVerificationStartCountryEnum": {
        "enum": [
          "LVA"
        ],
        "type": "string",
        "description": "* `LVA` - LVA"
      },
      "DigitalIdWalletApiIdcardEeWalletVerificationStartRequest": {
        "type": "object",
        "description": "Mulai verifikasi Estonian ID-card (EST).",
        "properties": {
          "vendor_data": {
            "type": "string",
            "nullable": true,
            "description": "Referensi Anda sendiri untuk verifikasi ini (mis. ID pengguna Anda). Dikembalikan dalam hasil dan webhook."
          },
          "metadata": {
            "type": "object",
            "additionalProperties": {},
            "nullable": true,
            "description": "Objek JSON opsional yang disimpan bersama verifikasi dan dikembalikan dalam hasil serta webhook."
          },
          "sandbox_scenario": {
            "type": "string",
            "minLength": 1,
            "description": "Khusus aplikasi sandbox: hasil simulasi - 'wallet_cancelled', 'wallet_timeout', atau 'wallet_provider_error'; skenario lain (atau tanpa skenario) akan lolos verifikasi. Ditolak pada aplikasi di lingkungan produksi. Katalog lengkap tersedia di GET /v1/sandbox/scenarios/."
          },
          "country": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DigitalIdWalletApiIdcardEeWalletVerificationStartCountryEnum"
              }
            ],
            "default": "EST",
            "description": "Negara ISO 3166-1 alpha-3 dari identitas Estonian ID-card. Default-nya adalah EST, satu-satunya negara yang dilayaninya.\n\n* `EST` - EST"
          },
          "return_url": {
            "type": "string",
            "format": "uri",
            "minLength": 1,
            "description": "URL https tempat peramban pengguna kembali setelah dompet, dengan request_id dan result ditambahkan. Host-nya harus terdaftar di allowed_return_hosts aplikasi (atau merupakan domain White Label miliknya). Jangan pernah memercayai result secara mandiri: baca hasilnya dengan GET .../verifications/{request_id}/ atau webhook.",
            "maxLength": 2048
          },
          "device": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DigitalIdWalletApiDeviceEnum"
              }
            ],
            "default": "same_device",
            "description": "same_device saat pengguna masuk di perangkat yang menampilkan halaman Anda, cross_device saat mereka menggunakan perangkat lain (misalnya kode QR BankID).\n\n* `same_device` - same_device\n* `cross_device` - cross_device"
          }
        },
        "required": [
          "return_url"
        ]
      },
      "DigitalIdWalletApiIdcardEeWalletVerificationStartCountryEnum": {
        "enum": [
          "EST"
        ],
        "type": "string",
        "description": "* `EST` - EST"
      },
      "DigitalIdWalletApiMobileIdWalletVerificationStartRequest": {
        "type": "object",
        "description": "Mulai verifikasi Mobile-ID (EST, LTU).",
        "properties": {
          "vendor_data": {
            "type": "string",
            "nullable": true,
            "description": "Referensi Anda sendiri untuk verifikasi ini (mis. ID pengguna Anda). Dikembalikan dalam hasil dan webhook."
          },
          "metadata": {
            "type": "object",
            "additionalProperties": {},
            "nullable": true,
            "description": "Objek JSON opsional yang disimpan bersama verifikasi dan dikembalikan dalam hasil serta webhook."
          },
          "sandbox_scenario": {
            "type": "string",
            "minLength": 1,
            "description": "Khusus aplikasi sandbox: hasil simulasi - 'wallet_cancelled', 'wallet_timeout', atau 'wallet_provider_error'; skenario lain (atau tanpa skenario) akan lolos verifikasi. Ditolak pada aplikasi di lingkungan produksi. Katalog lengkap tersedia di GET /v1/sandbox/scenarios/."
          },
          "country": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DigitalIdWalletApiMobileIdWalletVerificationStartCountryEnum"
              }
            ],
            "description": "Negara ISO 3166-1 alpha-3 dari identitas Mobile-ID.\n\n* `EST` - EST\n* `LTU` - LTU"
          },
          "personal_code": {
            "type": "string",
            "minLength": 1,
            "description": "Kode identifikasi pribadi nasional pengguna. Kode ini ditujukan ke aplikasi Mobile-ID pengguna; pengguna mengonfirmasi kode perbandingan dan memasukkan PIN mereka di aplikasi. Jangan pernah mengumpulkan PIN.",
            "pattern": "^[0-9-]{6,20}$"
          },
          "phone_number": {
            "type": "string",
            "minLength": 1,
            "description": "Nomor telepon Mobile-ID dalam format E.164 (+372... atau +370...).",
            "maxLength": 16
          }
        },
        "required": [
          "country",
          "personal_code",
          "phone_number"
        ]
      },
      "DigitalIdWalletApiMobileIdWalletVerificationStartCountryEnum": {
        "enum": [
          "EST",
          "LTU"
        ],
        "type": "string",
        "description": "* `EST` - EST\n* `LTU` - LTU"
      },
      "DigitalIdWalletApiSmartIdWalletVerificationStartRequest": {
        "type": "object",
        "description": "Mulai verifikasi Smart-ID (EST, LVA, LTU, BEL).",
        "properties": {
          "vendor_data": {
            "type": "string",
            "nullable": true,
            "description": "Referensi Anda sendiri untuk verifikasi ini (mis. ID pengguna Anda). Dikembalikan dalam hasil dan webhook."
          },
          "metadata": {
            "type": "object",
            "additionalProperties": {},
            "nullable": true,
            "description": "Objek JSON opsional yang disimpan bersama verifikasi dan dikembalikan dalam hasil serta webhook."
          },
          "sandbox_scenario": {
            "type": "string",
            "minLength": 1,
            "description": "Khusus aplikasi sandbox: hasil simulasi - 'wallet_cancelled', 'wallet_timeout', atau 'wallet_provider_error'; skenario lain (atau tanpa skenario) akan lolos verifikasi. Ditolak pada aplikasi di lingkungan produksi. Katalog lengkap tersedia di GET /v1/sandbox/scenarios/."
          },
          "country": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DigitalIdWalletApiSmartIdWalletVerificationStartCountryEnum"
              }
            ],
            "description": "Negara ISO 3166-1 alpha-3 dari identitas Smart-ID.\n\n* `EST` - EST\n* `LVA` - LVA\n* `LTU` - LTU\n* `BEL` - BEL"
          },
          "personal_code": {
            "type": "string",
            "minLength": 1,
            "description": "Kode identifikasi pribadi nasional pengguna. Kode ini ditujukan ke aplikasi Smart-ID pengguna; pengguna mengonfirmasi kode perbandingan dan memasukkan PIN mereka di aplikasi. Jangan pernah mengumpulkan PIN.",
            "pattern": "^[0-9-]{6,20}$"
          }
        },
        "required": [
          "country",
          "personal_code"
        ]
      },
      "DigitalIdWalletApiSmartIdWalletVerificationStartCountryEnum": {
        "enum": [
          "EST",
          "LVA",
          "LTU",
          "BEL"
        ],
        "type": "string",
        "description": "* `EST` - EST\n* `LVA` - LVA\n* `LTU` - LTU\n* `BEL` - BEL"
      },
      "DigitalIdWalletApiGovukWalletWalletVerificationStartRequest": {
        "type": "object",
        "description": "Mulai verifikasi GOV.UK Wallet (GBR).",
        "properties": {
          "vendor_data": {
            "type": "string",
            "nullable": true,
            "description": "Referensi Anda sendiri untuk verifikasi ini (mis. ID pengguna Anda). Dikembalikan dalam hasil dan webhook."
          },
          "metadata": {
            "type": "object",
            "additionalProperties": {},
            "nullable": true,
            "description": "Objek JSON opsional yang disimpan bersama verifikasi dan dikembalikan dalam hasil serta webhook."
          },
          "sandbox_scenario": {
            "type": "string",
            "minLength": 1,
            "description": "Khusus aplikasi sandbox: hasil simulasi - 'wallet_cancelled', 'wallet_timeout', atau 'wallet_provider_error'; skenario lain (atau tanpa skenario) akan lolos verifikasi. Ditolak pada aplikasi di lingkungan produksi. Katalog lengkap tersedia di GET /v1/sandbox/scenarios/."
          },
          "country": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DigitalIdWalletApiCountry520Enum"
              }
            ],
            "default": "GBR",
            "description": "Negara ISO 3166-1 alpha-3 dari identitas GOV.UK Wallet. Secara default, nilainya adalah GBR, satu-satunya negara yang dilayaninya.\n\n* `GBR` - GBR"
          },
          "return_url": {
            "type": "string",
            "format": "uri",
            "minLength": 1,
            "description": "URL https tempat peramban pengguna kembali setelah dompet, dengan request_id dan result ditambahkan. Host-nya harus terdaftar di allowed_return_hosts aplikasi (atau merupakan domain White Label miliknya). Jangan pernah memercayai result secara mandiri: baca hasilnya dengan GET .../verifications/{request_id}/ atau webhook.",
            "maxLength": 2048
          },
          "device": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DigitalIdWalletApiDeviceEnum"
              }
            ],
            "default": "same_device",
            "description": "same_device saat pengguna masuk di perangkat yang menampilkan halaman Anda, cross_device saat mereka menggunakan perangkat lain (misalnya kode QR BankID).\n\n* `same_device` - same_device\n* `cross_device` - cross_device"
          }
        },
        "required": [
          "return_url"
        ]
      },
      "DigitalIdWalletApiCountry520Enum": {
        "enum": [
          "GBR"
        ],
        "type": "string",
        "description": "* `GBR` - GBR"
      },
      "DigitalIdWalletApiOneidWalletVerificationStartRequest": {
        "type": "object",
        "description": "Mulai verifikasi OneID (GBR).",
        "properties": {
          "vendor_data": {
            "type": "string",
            "nullable": true,
            "description": "Referensi Anda sendiri untuk verifikasi ini (mis. ID pengguna Anda). Dikembalikan dalam hasil dan webhook."
          },
          "metadata": {
            "type": "object",
            "additionalProperties": {},
            "nullable": true,
            "description": "Objek JSON opsional yang disimpan bersama verifikasi dan dikembalikan dalam hasil serta webhook."
          },
          "sandbox_scenario": {
            "type": "string",
            "minLength": 1,
            "description": "Khusus aplikasi sandbox: hasil simulasi - 'wallet_cancelled', 'wallet_timeout', atau 'wallet_provider_error'; skenario lain (atau tanpa skenario) akan lolos verifikasi. Ditolak pada aplikasi di lingkungan produksi. Katalog lengkap tersedia di GET /v1/sandbox/scenarios/."
          },
          "country": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DigitalIdWalletApiCountry520Enum"
              }
            ],
            "default": "GBR",
            "description": "Negara ISO 3166-1 alpha-3 dari identitas OneID. Secara default, nilainya adalah GBR, satu-satunya negara yang dilayaninya.\n\n* `GBR` - GBR"
          },
          "return_url": {
            "type": "string",
            "format": "uri",
            "minLength": 1,
            "description": "URL https tempat peramban pengguna kembali setelah dompet, dengan request_id dan result ditambahkan. Host-nya harus terdaftar di allowed_return_hosts aplikasi (atau merupakan domain White Label miliknya). Jangan pernah memercayai result secara mandiri: baca hasilnya dengan GET .../verifications/{request_id}/ atau webhook.",
            "maxLength": 2048
          },
          "device": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DigitalIdWalletApiDeviceEnum"
              }
            ],
            "default": "same_device",
            "description": "same_device saat pengguna masuk di perangkat yang menampilkan halaman Anda, cross_device saat mereka menggunakan perangkat lain (misalnya kode QR BankID).\n\n* `same_device` - same_device\n* `cross_device` - cross_device"
          }
        },
        "required": [
          "return_url"
        ]
      },
      "DigitalIdWalletApiGovbrWalletVerificationStartRequest": {
        "type": "object",
        "description": "Mulai verifikasi gov.br (BRA).",
        "properties": {
          "vendor_data": {
            "type": "string",
            "nullable": true,
            "description": "Referensi Anda sendiri untuk verifikasi ini (mis. ID pengguna Anda). Dikembalikan dalam hasil dan webhook."
          },
          "metadata": {
            "type": "object",
            "additionalProperties": {},
            "nullable": true,
            "description": "Objek JSON opsional yang disimpan bersama verifikasi dan dikembalikan dalam hasil serta webhook."
          },
          "sandbox_scenario": {
            "type": "string",
            "minLength": 1,
            "description": "Khusus aplikasi sandbox: hasil simulasi - 'wallet_cancelled', 'wallet_timeout', atau 'wallet_provider_error'; skenario lain (atau tanpa skenario) akan lolos verifikasi. Ditolak pada aplikasi di lingkungan produksi. Katalog lengkap tersedia di GET /v1/sandbox/scenarios/."
          },
          "country": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DigitalIdWalletApiGovbrWalletVerificationStartCountryEnum"
              }
            ],
            "default": "BRA",
            "description": "Negara ISO 3166-1 alpha-3 dari identitas gov.br. Secara default bernilai BRA, satu-satunya negara yang dilayaninya.\n\n* `BRA` - BRA"
          },
          "return_url": {
            "type": "string",
            "format": "uri",
            "minLength": 1,
            "description": "URL https tempat peramban pengguna kembali setelah dompet, dengan request_id dan result ditambahkan. Host-nya harus terdaftar di allowed_return_hosts aplikasi (atau merupakan domain White Label miliknya). Jangan pernah memercayai result secara mandiri: baca hasilnya dengan GET .../verifications/{request_id}/ atau webhook.",
            "maxLength": 2048
          },
          "device": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DigitalIdWalletApiDeviceEnum"
              }
            ],
            "default": "same_device",
            "description": "same_device saat pengguna masuk di perangkat yang menampilkan halaman Anda, cross_device saat mereka menggunakan perangkat lain (misalnya kode QR BankID).\n\n* `same_device` - same_device\n* `cross_device` - cross_device"
          }
        },
        "required": [
          "return_url"
        ]
      },
      "DigitalIdWalletApiGovbrWalletVerificationStartCountryEnum": {
        "enum": [
          "BRA"
        ],
        "type": "string",
        "description": "* `BRA` - BRA"
      },
      "DigitalIdWalletApiUaePassWalletVerificationStartRequest": {
        "type": "object",
        "description": "Mulai verifikasi UAE PASS (ARE).",
        "properties": {
          "vendor_data": {
            "type": "string",
            "nullable": true,
            "description": "Referensi Anda sendiri untuk verifikasi ini (mis. ID pengguna Anda). Dikembalikan dalam hasil dan webhook."
          },
          "metadata": {
            "type": "object",
            "additionalProperties": {},
            "nullable": true,
            "description": "Objek JSON opsional yang disimpan bersama verifikasi dan dikembalikan dalam hasil serta webhook."
          },
          "sandbox_scenario": {
            "type": "string",
            "minLength": 1,
            "description": "Khusus aplikasi sandbox: hasil simulasi - 'wallet_cancelled', 'wallet_timeout', atau 'wallet_provider_error'; skenario lain (atau tanpa skenario) akan lolos verifikasi. Ditolak pada aplikasi di lingkungan produksi. Katalog lengkap tersedia di GET /v1/sandbox/scenarios/."
          },
          "country": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DigitalIdWalletApiUaePassWalletVerificationStartCountryEnum"
              }
            ],
            "default": "ARE",
            "description": "Negara ISO 3166-1 alpha-3 dari identitas UAE PASS. Secara default, nilainya adalah ARE, satu-satunya negara yang dilayaninya.\n\n* `ARE` - ARE"
          },
          "return_url": {
            "type": "string",
            "format": "uri",
            "minLength": 1,
            "description": "URL https tempat peramban pengguna kembali setelah dompet, dengan request_id dan result ditambahkan. Host-nya harus terdaftar di allowed_return_hosts aplikasi (atau merupakan domain White Label miliknya). Jangan pernah memercayai result secara mandiri: baca hasilnya dengan GET .../verifications/{request_id}/ atau webhook.",
            "maxLength": 2048
          },
          "device": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DigitalIdWalletApiDeviceEnum"
              }
            ],
            "default": "same_device",
            "description": "same_device saat pengguna masuk di perangkat yang menampilkan halaman Anda, cross_device saat mereka menggunakan perangkat lain (misalnya kode QR BankID).\n\n* `same_device` - same_device\n* `cross_device` - cross_device"
          }
        },
        "required": [
          "return_url"
        ]
      },
      "DigitalIdWalletApiUaePassWalletVerificationStartCountryEnum": {
        "enum": [
          "ARE"
        ],
        "type": "string",
        "description": "* `ARE` - ARE"
      },
      "DigitalIdWalletApiFrejaidWalletVerificationStartRequest": {
        "type": "object",
        "description": "Mulai verifikasi Freja eID (SWE).",
        "properties": {
          "vendor_data": {
            "type": "string",
            "nullable": true,
            "description": "Referensi Anda sendiri untuk verifikasi ini (mis. ID pengguna Anda). Dikembalikan dalam hasil dan webhook."
          },
          "metadata": {
            "type": "object",
            "additionalProperties": {},
            "nullable": true,
            "description": "Objek JSON opsional yang disimpan bersama verifikasi dan dikembalikan dalam hasil serta webhook."
          },
          "sandbox_scenario": {
            "type": "string",
            "minLength": 1,
            "description": "Khusus aplikasi sandbox: hasil simulasi - 'wallet_cancelled', 'wallet_timeout', atau 'wallet_provider_error'; skenario lain (atau tanpa skenario) akan lolos verifikasi. Ditolak pada aplikasi di lingkungan produksi. Katalog lengkap tersedia di GET /v1/sandbox/scenarios/."
          },
          "country": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DigitalIdWalletApiCountryEe9Enum"
              }
            ],
            "default": "SWE",
            "description": "Negara ISO 3166-1 alpha-3 dari identitas Freja eID. Secara default bernilai SWE, satu-satunya negara yang dilayaninya.\n\n* `SWE` - SWE"
          },
          "return_url": {
            "type": "string",
            "format": "uri",
            "minLength": 1,
            "description": "URL https tempat peramban pengguna kembali setelah dompet, dengan request_id dan result ditambahkan. Host-nya harus terdaftar di allowed_return_hosts aplikasi (atau merupakan domain White Label miliknya). Jangan pernah memercayai result secara mandiri: baca hasilnya dengan GET .../verifications/{request_id}/ atau webhook.",
            "maxLength": 2048
          },
          "device": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DigitalIdWalletApiDeviceEnum"
              }
            ],
            "default": "same_device",
            "description": "same_device saat pengguna masuk di perangkat yang menampilkan halaman Anda, cross_device saat mereka menggunakan perangkat lain (misalnya kode QR BankID).\n\n* `same_device` - same_device\n* `cross_device` - cross_device"
          }
        },
        "required": [
          "return_url"
        ]
      },
      "DigitalIdWalletApiCountryEe9Enum": {
        "enum": [
          "SWE"
        ],
        "type": "string",
        "description": "* `SWE` - SWE"
      },
      "DigitalIdWalletApiPersonalausweisWalletVerificationStartRequest": {
        "type": "object",
        "description": "Mulai verifikasi Personalausweis (DEU).",
        "properties": {
          "vendor_data": {
            "type": "string",
            "nullable": true,
            "description": "Referensi Anda sendiri untuk verifikasi ini (mis. ID pengguna Anda). Dikembalikan dalam hasil dan webhook."
          },
          "metadata": {
            "type": "object",
            "additionalProperties": {},
            "nullable": true,
            "description": "Objek JSON opsional yang disimpan bersama verifikasi dan dikembalikan dalam hasil serta webhook."
          },
          "sandbox_scenario": {
            "type": "string",
            "minLength": 1,
            "description": "Khusus aplikasi sandbox: hasil simulasi - 'wallet_cancelled', 'wallet_timeout', atau 'wallet_provider_error'; skenario lain (atau tanpa skenario) akan lolos verifikasi. Ditolak pada aplikasi di lingkungan produksi. Katalog lengkap tersedia di GET /v1/sandbox/scenarios/."
          },
          "country": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DigitalIdWalletApiPersonalausweisWalletVerificationStartCountryEnum"
              }
            ],
            "default": "DEU",
            "description": "Negara ISO 3166-1 alpha-3 dari identitas Personalausweis. Secara default, nilainya adalah DEU, satu-satunya negara yang dilayaninya.\n\n* `DEU` - DEU"
          },
          "return_url": {
            "type": "string",
            "format": "uri",
            "minLength": 1,
            "description": "URL https tempat peramban pengguna kembali setelah dompet, dengan request_id dan result ditambahkan. Host-nya harus terdaftar di allowed_return_hosts aplikasi (atau merupakan domain White Label miliknya). Jangan pernah memercayai result secara mandiri: baca hasilnya dengan GET .../verifications/{request_id}/ atau webhook.",
            "maxLength": 2048
          },
          "device": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DigitalIdWalletApiDeviceEnum"
              }
            ],
            "default": "same_device",
            "description": "same_device saat pengguna masuk di perangkat yang menampilkan halaman Anda, cross_device saat mereka menggunakan perangkat lain (misalnya kode QR BankID).\n\n* `same_device` - same_device\n* `cross_device` - cross_device"
          }
        },
        "required": [
          "return_url"
        ]
      },
      "DigitalIdWalletApiPersonalausweisWalletVerificationStartCountryEnum": {
        "enum": [
          "DEU"
        ],
        "type": "string",
        "description": "* `DEU` - DEU"
      },
      "DigitalIdWalletApiFtnWalletVerificationStartRequest": {
        "type": "object",
        "description": "Mulai verifikasi Finnish Trust Network (FIN).",
        "properties": {
          "vendor_data": {
            "type": "string",
            "nullable": true,
            "description": "Referensi Anda sendiri untuk verifikasi ini (mis. ID pengguna Anda). Dikembalikan dalam hasil dan webhook."
          },
          "metadata": {
            "type": "object",
            "additionalProperties": {},
            "nullable": true,
            "description": "Objek JSON opsional yang disimpan bersama verifikasi dan dikembalikan dalam hasil serta webhook."
          },
          "sandbox_scenario": {
            "type": "string",
            "minLength": 1,
            "description": "Khusus aplikasi sandbox: hasil simulasi - 'wallet_cancelled', 'wallet_timeout', atau 'wallet_provider_error'; skenario lain (atau tanpa skenario) akan lolos verifikasi. Ditolak pada aplikasi di lingkungan produksi. Katalog lengkap tersedia di GET /v1/sandbox/scenarios/."
          },
          "country": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DigitalIdWalletApiFtnWalletVerificationStartCountryEnum"
              }
            ],
            "default": "FIN",
            "description": "Negara ISO 3166-1 alpha-3 dari identitas Finnish Trust Network. Default-nya adalah FIN, satu-satunya negara yang dilayaninya.\n\n* `FIN` - FIN"
          },
          "return_url": {
            "type": "string",
            "format": "uri",
            "minLength": 1,
            "description": "URL https tempat peramban pengguna kembali setelah dompet, dengan request_id dan result ditambahkan. Host-nya harus terdaftar di allowed_return_hosts aplikasi (atau merupakan domain White Label miliknya). Jangan pernah memercayai result secara mandiri: baca hasilnya dengan GET .../verifications/{request_id}/ atau webhook.",
            "maxLength": 2048
          },
          "device": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DigitalIdWalletApiDeviceEnum"
              }
            ],
            "default": "same_device",
            "description": "same_device saat pengguna masuk di perangkat yang menampilkan halaman Anda, cross_device saat mereka menggunakan perangkat lain (misalnya kode QR BankID).\n\n* `same_device` - same_device\n* `cross_device` - cross_device"
          }
        },
        "required": [
          "return_url"
        ]
      },
      "DigitalIdWalletApiFtnWalletVerificationStartCountryEnum": {
        "enum": [
          "FIN"
        ],
        "type": "string",
        "description": "* `FIN` - FIN"
      },
      "DigitalIdWalletApiIdinWalletVerificationStartRequest": {
        "type": "object",
        "description": "Mulai verifikasi iDIN (NLD).",
        "properties": {
          "vendor_data": {
            "type": "string",
            "nullable": true,
            "description": "Referensi Anda sendiri untuk verifikasi ini (mis. ID pengguna Anda). Dikembalikan dalam hasil dan webhook."
          },
          "metadata": {
            "type": "object",
            "additionalProperties": {},
            "nullable": true,
            "description": "Objek JSON opsional yang disimpan bersama verifikasi dan dikembalikan dalam hasil serta webhook."
          },
          "sandbox_scenario": {
            "type": "string",
            "minLength": 1,
            "description": "Khusus aplikasi sandbox: hasil simulasi - 'wallet_cancelled', 'wallet_timeout', atau 'wallet_provider_error'; skenario lain (atau tanpa skenario) akan lolos verifikasi. Ditolak pada aplikasi di lingkungan produksi. Katalog lengkap tersedia di GET /v1/sandbox/scenarios/."
          },
          "country": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DigitalIdWalletApiIdinWalletVerificationStartCountryEnum"
              }
            ],
            "default": "NLD",
            "description": "Negara ISO 3166-1 alpha-3 dari identitas iDIN. Secara default, nilainya adalah NLD, satu-satunya negara yang dilayaninya.\n\n* `NLD` - NLD"
          },
          "return_url": {
            "type": "string",
            "format": "uri",
            "minLength": 1,
            "description": "URL https tempat peramban pengguna kembali setelah dompet, dengan request_id dan result ditambahkan. Host-nya harus terdaftar di allowed_return_hosts aplikasi (atau merupakan domain White Label miliknya). Jangan pernah memercayai result secara mandiri: baca hasilnya dengan GET .../verifications/{request_id}/ atau webhook.",
            "maxLength": 2048
          },
          "device": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DigitalIdWalletApiDeviceEnum"
              }
            ],
            "default": "same_device",
            "description": "same_device saat pengguna masuk di perangkat yang menampilkan halaman Anda, cross_device saat mereka menggunakan perangkat lain (misalnya kode QR BankID).\n\n* `same_device` - same_device\n* `cross_device` - cross_device"
          }
        },
        "required": [
          "return_url"
        ]
      },
      "DigitalIdWalletApiIdinWalletVerificationStartCountryEnum": {
        "enum": [
          "NLD"
        ],
        "type": "string",
        "description": "* `NLD` - NLD"
      },
      "DigitalIdWalletApiItsmeWalletVerificationStartRequest": {
        "type": "object",
        "description": "Mulai verifikasi itsme (BEL, LUX, NLD).",
        "properties": {
          "vendor_data": {
            "type": "string",
            "nullable": true,
            "description": "Referensi Anda sendiri untuk verifikasi ini (mis. ID pengguna Anda). Dikembalikan dalam hasil dan webhook."
          },
          "metadata": {
            "type": "object",
            "additionalProperties": {},
            "nullable": true,
            "description": "Objek JSON opsional yang disimpan bersama verifikasi dan dikembalikan dalam hasil serta webhook."
          },
          "sandbox_scenario": {
            "type": "string",
            "minLength": 1,
            "description": "Khusus aplikasi sandbox: hasil simulasi - 'wallet_cancelled', 'wallet_timeout', atau 'wallet_provider_error'; skenario lain (atau tanpa skenario) akan lolos verifikasi. Ditolak pada aplikasi di lingkungan produksi. Katalog lengkap tersedia di GET /v1/sandbox/scenarios/."
          },
          "country": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DigitalIdWalletApiItsmeWalletVerificationStartCountryEnum"
              }
            ],
            "description": "Negara ISO 3166-1 alpha-3 dari identitas itsme.\n\n* `BEL` - BEL\n* `LUX` - LUX\n* `NLD` - NLD"
          },
          "return_url": {
            "type": "string",
            "format": "uri",
            "minLength": 1,
            "description": "URL https tempat peramban pengguna kembali setelah dompet, dengan request_id dan result ditambahkan. Host-nya harus terdaftar di allowed_return_hosts aplikasi (atau merupakan domain White Label miliknya). Jangan pernah memercayai result secara mandiri: baca hasilnya dengan GET .../verifications/{request_id}/ atau webhook.",
            "maxLength": 2048
          },
          "device": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DigitalIdWalletApiDeviceEnum"
              }
            ],
            "default": "same_device",
            "description": "same_device saat pengguna masuk di perangkat yang menampilkan halaman Anda, cross_device saat mereka menggunakan perangkat lain (misalnya kode QR BankID).\n\n* `same_device` - same_device\n* `cross_device` - cross_device"
          }
        },
        "required": [
          "country",
          "return_url"
        ]
      },
      "DigitalIdWalletApiItsmeWalletVerificationStartCountryEnum": {
        "enum": [
          "BEL",
          "LUX",
          "NLD"
        ],
        "type": "string",
        "description": "* `BEL` - BEL\n* `LUX` - LUX\n* `NLD` - NLD"
      },
      "DigitalIdWalletApiBuypassWalletVerificationStartRequest": {
        "type": "object",
        "description": "Mulai verifikasi Buypass ID (NOR).",
        "properties": {
          "vendor_data": {
            "type": "string",
            "nullable": true,
            "description": "Referensi Anda sendiri untuk verifikasi ini (mis. ID pengguna Anda). Dikembalikan dalam hasil dan webhook."
          },
          "metadata": {
            "type": "object",
            "additionalProperties": {},
            "nullable": true,
            "description": "Objek JSON opsional yang disimpan bersama verifikasi dan dikembalikan dalam hasil serta webhook."
          },
          "sandbox_scenario": {
            "type": "string",
            "minLength": 1,
            "description": "Khusus aplikasi sandbox: hasil simulasi - 'wallet_cancelled', 'wallet_timeout', atau 'wallet_provider_error'; skenario lain (atau tanpa skenario) akan lolos verifikasi. Ditolak pada aplikasi di lingkungan produksi. Katalog lengkap tersedia di GET /v1/sandbox/scenarios/."
          },
          "country": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DigitalIdWalletApiCountryAfcEnum"
              }
            ],
            "default": "NOR",
            "description": "Negara ISO 3166-1 alpha-3 dari identitas Buypass ID. Default-nya adalah NOR, satu-satunya negara yang dilayaninya.\n\n* `NOR` - NOR"
          },
          "return_url": {
            "type": "string",
            "format": "uri",
            "minLength": 1,
            "description": "URL https tempat peramban pengguna kembali setelah dompet, dengan request_id dan result ditambahkan. Host-nya harus terdaftar di allowed_return_hosts aplikasi (atau merupakan domain White Label miliknya). Jangan pernah memercayai result secara mandiri: baca hasilnya dengan GET .../verifications/{request_id}/ atau webhook.",
            "maxLength": 2048
          },
          "device": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DigitalIdWalletApiDeviceEnum"
              }
            ],
            "default": "same_device",
            "description": "same_device saat pengguna masuk di perangkat yang menampilkan halaman Anda, cross_device saat mereka menggunakan perangkat lain (misalnya kode QR BankID).\n\n* `same_device` - same_device\n* `cross_device` - cross_device"
          }
        },
        "required": [
          "return_url"
        ]
      },
      "DigitalIdWalletApiCountryAfcEnum": {
        "enum": [
          "NOR"
        ],
        "type": "string",
        "description": "* `NOR` - NOR"
      },
      "DigitalIdWalletApiVippsWalletVerificationStartRequest": {
        "type": "object",
        "description": "Mulai verifikasi Vipps (NOR).",
        "properties": {
          "vendor_data": {
            "type": "string",
            "nullable": true,
            "description": "Referensi Anda sendiri untuk verifikasi ini (mis. ID pengguna Anda). Dikembalikan dalam hasil dan webhook."
          },
          "metadata": {
            "type": "object",
            "additionalProperties": {},
            "nullable": true,
            "description": "Objek JSON opsional yang disimpan bersama verifikasi dan dikembalikan dalam hasil serta webhook."
          },
          "sandbox_scenario": {
            "type": "string",
            "minLength": 1,
            "description": "Khusus aplikasi sandbox: hasil simulasi - 'wallet_cancelled', 'wallet_timeout', atau 'wallet_provider_error'; skenario lain (atau tanpa skenario) akan lolos verifikasi. Ditolak pada aplikasi di lingkungan produksi. Katalog lengkap tersedia di GET /v1/sandbox/scenarios/."
          },
          "country": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DigitalIdWalletApiCountryAfcEnum"
              }
            ],
            "default": "NOR",
            "description": "Negara ISO 3166-1 alpha-3 dari identitas Vipps. Secara default nilainya adalah NOR, satu-satunya negara yang dilayaninya.\n\n* `NOR` - NOR"
          },
          "return_url": {
            "type": "string",
            "format": "uri",
            "minLength": 1,
            "description": "URL https tempat peramban pengguna kembali setelah dompet, dengan request_id dan result ditambahkan. Host-nya harus terdaftar di allowed_return_hosts aplikasi (atau merupakan domain White Label miliknya). Jangan pernah memercayai result secara mandiri: baca hasilnya dengan GET .../verifications/{request_id}/ atau webhook.",
            "maxLength": 2048
          },
          "device": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DigitalIdWalletApiDeviceEnum"
              }
            ],
            "default": "same_device",
            "description": "same_device saat pengguna masuk di perangkat yang menampilkan halaman Anda, cross_device saat mereka menggunakan perangkat lain (misalnya kode QR BankID).\n\n* `same_device` - same_device\n* `cross_device` - cross_device"
          }
        },
        "required": [
          "return_url"
        ]
      },
      "DigitalIdWalletApiBankidNoWalletVerificationStartRequest": {
        "type": "object",
        "description": "Mulai verifikasi BankID (NOR).",
        "properties": {
          "vendor_data": {
            "type": "string",
            "nullable": true,
            "description": "Referensi Anda sendiri untuk verifikasi ini (mis. ID pengguna Anda). Dikembalikan dalam hasil dan webhook."
          },
          "metadata": {
            "type": "object",
            "additionalProperties": {},
            "nullable": true,
            "description": "Objek JSON opsional yang disimpan bersama verifikasi dan dikembalikan dalam hasil serta webhook."
          },
          "sandbox_scenario": {
            "type": "string",
            "minLength": 1,
            "description": "Khusus aplikasi sandbox: hasil simulasi - 'wallet_cancelled', 'wallet_timeout', atau 'wallet_provider_error'; skenario lain (atau tanpa skenario) akan lolos verifikasi. Ditolak pada aplikasi di lingkungan produksi. Katalog lengkap tersedia di GET /v1/sandbox/scenarios/."
          },
          "country": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DigitalIdWalletApiCountryAfcEnum"
              }
            ],
            "default": "NOR",
            "description": "Negara ISO 3166-1 alpha-3 dari identitas BankID. Default-nya adalah NOR, satu-satunya negara yang dilayaninya.\n\n* `NOR` - NOR"
          },
          "return_url": {
            "type": "string",
            "format": "uri",
            "minLength": 1,
            "description": "URL https tempat peramban pengguna kembali setelah dompet, dengan request_id dan result ditambahkan. Host-nya harus terdaftar di allowed_return_hosts aplikasi (atau merupakan domain White Label miliknya). Jangan pernah memercayai result secara mandiri: baca hasilnya dengan GET .../verifications/{request_id}/ atau webhook.",
            "maxLength": 2048
          },
          "device": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DigitalIdWalletApiDeviceEnum"
              }
            ],
            "default": "same_device",
            "description": "same_device saat pengguna masuk di perangkat yang menampilkan halaman Anda, cross_device saat mereka menggunakan perangkat lain (misalnya kode QR BankID).\n\n* `same_device` - same_device\n* `cross_device` - cross_device"
          }
        },
        "required": [
          "return_url"
        ]
      },
      "DigitalIdWalletApiBankidSeWalletVerificationStartRequest": {
        "type": "object",
        "description": "Mulai verifikasi BankID (SWE).",
        "properties": {
          "vendor_data": {
            "type": "string",
            "nullable": true,
            "description": "Referensi Anda sendiri untuk verifikasi ini (mis. ID pengguna Anda). Dikembalikan dalam hasil dan webhook."
          },
          "metadata": {
            "type": "object",
            "additionalProperties": {},
            "nullable": true,
            "description": "Objek JSON opsional yang disimpan bersama verifikasi dan dikembalikan dalam hasil serta webhook."
          },
          "sandbox_scenario": {
            "type": "string",
            "minLength": 1,
            "description": "Khusus aplikasi sandbox: hasil simulasi - 'wallet_cancelled', 'wallet_timeout', atau 'wallet_provider_error'; skenario lain (atau tanpa skenario) akan lolos verifikasi. Ditolak pada aplikasi di lingkungan produksi. Katalog lengkap tersedia di GET /v1/sandbox/scenarios/."
          },
          "country": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DigitalIdWalletApiCountryEe9Enum"
              }
            ],
            "default": "SWE",
            "description": "Negara ISO 3166-1 alpha-3 dari identitas BankID. Default-nya adalah SWE, satu-satunya negara yang dilayaninya.\n\n* `SWE` - SWE"
          },
          "return_url": {
            "type": "string",
            "format": "uri",
            "minLength": 1,
            "description": "URL https tempat peramban pengguna kembali setelah dompet, dengan request_id dan result ditambahkan. Host-nya harus terdaftar di allowed_return_hosts aplikasi (atau merupakan domain White Label miliknya). Jangan pernah memercayai result secara mandiri: baca hasilnya dengan GET .../verifications/{request_id}/ atau webhook.",
            "maxLength": 2048
          },
          "device": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DigitalIdWalletApiDeviceEnum"
              }
            ],
            "default": "same_device",
            "description": "same_device saat pengguna masuk di perangkat yang menampilkan halaman Anda, cross_device saat mereka menggunakan perangkat lain (misalnya kode QR BankID).\n\n* `same_device` - same_device\n* `cross_device` - cross_device"
          }
        },
        "required": [
          "return_url"
        ]
      },
      "DigitalIdWalletApiMitidWalletVerificationStartRequest": {
        "type": "object",
        "description": "Mulai verifikasi MitID (DNK).",
        "properties": {
          "vendor_data": {
            "type": "string",
            "nullable": true,
            "description": "Referensi Anda sendiri untuk verifikasi ini (mis. ID pengguna Anda). Dikembalikan dalam hasil dan webhook."
          },
          "metadata": {
            "type": "object",
            "additionalProperties": {},
            "nullable": true,
            "description": "Objek JSON opsional yang disimpan bersama verifikasi dan dikembalikan dalam hasil serta webhook."
          },
          "sandbox_scenario": {
            "type": "string",
            "minLength": 1,
            "description": "Khusus aplikasi sandbox: hasil simulasi - 'wallet_cancelled', 'wallet_timeout', atau 'wallet_provider_error'; skenario lain (atau tanpa skenario) akan lolos verifikasi. Ditolak pada aplikasi di lingkungan produksi. Katalog lengkap tersedia di GET /v1/sandbox/scenarios/."
          },
          "country": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DigitalIdWalletApiMitidWalletVerificationStartCountryEnum"
              }
            ],
            "default": "DNK",
            "description": "Negara ISO 3166-1 alpha-3 dari identitas MitID. Secara default, nilainya adalah DNK, satu-satunya negara yang dilayaninya.\n\n* `DNK` - DNK"
          },
          "return_url": {
            "type": "string",
            "format": "uri",
            "minLength": 1,
            "description": "URL https tempat peramban pengguna kembali setelah dompet, dengan request_id dan result ditambahkan. Host-nya harus terdaftar di allowed_return_hosts aplikasi (atau merupakan domain White Label miliknya). Jangan pernah memercayai result secara mandiri: baca hasilnya dengan GET .../verifications/{request_id}/ atau webhook.",
            "maxLength": 2048
          },
          "device": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DigitalIdWalletApiDeviceEnum"
              }
            ],
            "default": "same_device",
            "description": "same_device saat pengguna masuk di perangkat yang menampilkan halaman Anda, cross_device saat mereka menggunakan perangkat lain (misalnya kode QR BankID).\n\n* `same_device` - same_device\n* `cross_device` - cross_device"
          }
        },
        "required": [
          "return_url"
        ]
      },
      "DigitalIdWalletApiMitidWalletVerificationStartCountryEnum": {
        "enum": [
          "DNK"
        ],
        "type": "string",
        "description": "* `DNK` - DNK"
      },
      "DigitalIdWalletApiWalletCatalogResponse": {
        "type": "object",
        "properties": {
          "wallets": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/DigitalIdWalletApiWalletCatalogEntry"
            }
          }
        },
        "required": [
          "wallets"
        ]
      },
      "DigitalIdWalletApiWalletCatalogEntry": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "path": {
            "type": "string",
            "description": "Endpoint awal milik dompet itu sendiri."
          },
          "countries": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "issuing_authority": {
            "type": "string"
          },
          "level_of_assurance": {
            "type": "string",
            "nullable": true
          },
          "interaction": {
            "$ref": "#/components/schemas/DigitalIdWalletApiInteractionEnum"
          },
          "required_fields": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "available": {
            "type": "boolean",
            "description": "Apakah aplikasi ini dapat memulainya di lingkungan ini sekarang. Terdaftar tidak berarti aktif."
          }
        },
        "required": [
          "available",
          "countries",
          "id",
          "interaction",
          "issuing_authority",
          "level_of_assurance",
          "name",
          "path",
          "required_fields"
        ]
      },
      "CaseDuplicateCaseDuplicate": {
        "type": "object",
        "properties": {
          "uuid": {
            "type": "string",
            "format": "uuid",
            "readOnly": true
          },
          "case_number": {
            "type": "string",
            "nullable": true,
            "maxLength": 32
          },
          "title": {
            "type": "string",
            "maxLength": 255
          },
          "status": {
            "$ref": "#/components/schemas/CaseDuplicateStatusEnum"
          },
          "priority": {
            "$ref": "#/components/schemas/CaseDuplicatePriorityEnum"
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "readOnly": true
          }
        },
        "required": [
          "created_at",
          "title",
          "uuid"
        ]
      },
      "CaseDuplicateCaseDuplicatePage": {
        "type": "object",
        "properties": {
          "count": {
            "type": "integer"
          },
          "next_offset": {
            "type": "integer",
            "nullable": true
          },
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CaseDuplicateCaseDuplicate"
            }
          }
        },
        "required": [
          "count",
          "next_offset",
          "results"
        ]
      },
      "RoutingPublicationPolicyDraftResponse": {
        "type": "object",
        "properties": {
          "draft": {
            "allOf": [
              {
                "$ref": "#/components/schemas/RoutingPublicationPolicyDraft"
              }
            ],
            "nullable": true
          }
        },
        "required": [
          "draft"
        ]
      },
      "RoutingPublicationPolicyDraftWriteRequest": {
        "type": "object",
        "properties": {
          "expected_version": {
            "type": "integer",
            "minimum": 0
          },
          "expected_revision": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "changes": {
            "type": "object",
            "additionalProperties": {}
          }
        },
        "required": [
          "changes",
          "expected_revision",
          "expected_version"
        ]
      },
      "CasePublicationPolicyDraft": {
        "type": "object",
        "properties": {
          "revision": {
            "type": "string",
            "format": "uuid"
          },
          "base_version": {
            "type": "integer",
            "maximum": 2147483647,
            "minimum": 0
          },
          "changes": {},
          "actor_email": {
            "type": "string",
            "format": "email",
            "nullable": true,
            "maxLength": 254
          },
          "updated_at": {
            "type": "string",
            "format": "date-time",
            "readOnly": true
          }
        },
        "required": [
          "base_version",
          "updated_at"
        ]
      },
      "CasePublicationPolicyDraftPreconditionRequest": {
        "type": "object",
        "properties": {
          "expected_version": {
            "type": "integer",
            "minimum": 0
          },
          "expected_revision": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          }
        },
        "required": [
          "expected_revision",
          "expected_version"
        ]
      },
      "CaseCollaborationCaseNote": {
        "type": "object",
        "properties": {
          "uuid": {
            "type": "string",
            "format": "uuid",
            "readOnly": true
          },
          "comment": {
            "type": "string"
          },
          "actor_email": {
            "type": "string",
            "format": "email",
            "nullable": true,
            "maxLength": 255
          },
          "actor_name": {
            "type": "string",
            "nullable": true,
            "maxLength": 255
          },
          "mentioned_emails": {},
          "is_internal": {
            "type": "boolean"
          },
          "attachments": {},
          "tags": {},
          "created_at": {
            "type": "string",
            "format": "date-time",
            "readOnly": true
          },
          "reply_to": {
            "allOf": [
              {
                "$ref": "#/components/schemas/CaseCollaborationCaseNoteReply"
              }
            ],
            "nullable": true,
            "readOnly": true
          },
          "is_pinned": {
            "type": "boolean"
          },
          "client_reference": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          }
        },
        "required": [
          "comment",
          "created_at",
          "reply_to",
          "uuid"
        ]
      },
      "CustomerMessagingPaginatedCaseRequestList": {
        "type": "object",
        "required": [
          "count",
          "results"
        ],
        "properties": {
          "count": {
            "type": "integer",
            "example": 123
          },
          "next": {
            "type": "string",
            "nullable": true,
            "format": "uri",
            "example": "http://api.example.org/accounts/?offset=400&limit=100"
          },
          "previous": {
            "type": "string",
            "nullable": true,
            "format": "uri",
            "example": "http://api.example.org/accounts/?offset=200&limit=100"
          },
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CustomerMessagingCaseRequest"
            }
          }
        }
      },
      "FraudCheckResponse": {
        "type": "object",
        "properties": {
          "check_id": {
            "type": "string",
            "format": "uuid"
          },
          "request_id": {
            "type": "string",
            "format": "uuid",
            "description": "Sesi verifikasi native dibuat untuk pemeriksaan ini."
          },
          "client_reference": {
            "type": "string",
            "nullable": true
          },
          "processing_status": {
            "$ref": "#/components/schemas/FraudProcessingStatusEnum"
          },
          "profile_id": {
            "type": "string"
          },
          "profile_version": {
            "type": "string"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "completed_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "inputs": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FraudCheckInput"
            }
          },
          "modules": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FraudCheckModuleReport"
            }
          },
          "attribute_evidence": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": {}
            }
          },
          "compound_evidence": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": {}
            }
          },
          "risk": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FraudCheckRisk"
            }
          },
          "network": {
            "type": "object",
            "additionalProperties": {}
          },
          "enrichment": {
            "type": "object",
            "additionalProperties": {}
          },
          "identity_relationship": {
            "allOf": [
              {
                "$ref": "#/components/schemas/FraudCheckIdentityRelationship"
              }
            ],
            "nullable": true
          },
          "recommendation": {
            "$ref": "#/components/schemas/FraudRecommendationEnum"
          },
          "next_action": {
            "$ref": "#/components/schemas/FraudNextActionEnum"
          },
          "decision_reasons": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "coverage": {
            "type": "object",
            "additionalProperties": {}
          },
          "usage": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": {}
            }
          },
          "vendor_data": {
            "type": "string",
            "nullable": true
          },
          "metadata": {
            "nullable": true
          }
        },
        "required": [
          "attribute_evidence",
          "check_id",
          "client_reference",
          "completed_at",
          "compound_evidence",
          "coverage",
          "created_at",
          "decision_reasons",
          "inputs",
          "modules",
          "network",
          "next_action",
          "processing_status",
          "profile_id",
          "profile_version",
          "recommendation",
          "risk",
          "usage"
        ]
      },
      "CaseReviewTeam": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "maxLength": 100
          },
          "description": {
            "type": "string",
            "maxLength": 500
          },
          "members": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CaseReviewTeamMember"
            },
            "maxItems": 250
          },
          "is_active": {
            "type": "boolean"
          },
          "uuid": {
            "type": "string",
            "format": "uuid",
            "readOnly": true
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "readOnly": true
          },
          "updated_at": {
            "type": "string",
            "format": "date-time",
            "readOnly": true
          }
        }
      },
      "CaseActionCaseEntityActionRequest": {
        "type": "object",
        "properties": {
          "client_reference": {
            "type": "string",
            "format": "uuid"
          },
          "retry": {
            "type": "boolean",
            "default": false
          },
          "action": {
            "$ref": "#/components/schemas/CaseActionActionEnum"
          },
          "status": {
            "type": "string",
            "nullable": true
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "string",
              "minLength": 1
            }
          },
          "note": {
            "type": "string",
            "nullable": true
          }
        },
        "required": [
          "action"
        ]
      },
      "RoutingPublicationPaginatedPolicyRevisionList": {
        "type": "object",
        "required": [
          "count",
          "results"
        ],
        "properties": {
          "count": {
            "type": "integer",
            "example": 123
          },
          "next": {
            "type": "string",
            "nullable": true,
            "format": "uri",
            "example": "http://api.example.org/accounts/?offset=400&limit=100"
          },
          "previous": {
            "type": "string",
            "nullable": true,
            "format": "uri",
            "example": "http://api.example.org/accounts/?offset=200&limit=100"
          },
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/RoutingPublicationPolicyRevision"
            }
          }
        }
      },
      "FraudRecommendationEnum": {
        "enum": [
          "approve",
          "review",
          "reject"
        ],
        "type": "string",
        "description": "* `approve` - Setujui\n* `review` - Tinjau\n* `reject` - Tolak"
      },
      "CustomerMessagingCaseRequestPreviewResponse": {
        "type": "object",
        "properties": {
          "request_id": {
            "type": "string",
            "format": "uuid"
          },
          "expires_at": {
            "type": "string",
            "format": "date-time"
          },
          "recipient": {
            "type": "string",
            "format": "email"
          },
          "sender": {
            "type": "string"
          },
          "subject": {
            "type": "string"
          },
          "html": {
            "type": "string"
          },
          "requires_user_action": {
            "type": "boolean"
          },
          "preview_token": {
            "type": "string"
          }
        },
        "required": [
          "expires_at",
          "html",
          "preview_token",
          "recipient",
          "request_id",
          "requires_user_action",
          "sender",
          "subject"
        ]
      },
      "CustomerMessagingCaseCustomerResponseRequest": {
        "type": "object",
        "properties": {
          "full_name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 512
          },
          "date_of_birth": {
            "type": "string",
            "format": "date"
          },
          "file": {
            "type": "string",
            "format": "binary",
            "writeOnly": true
          }
        }
      },
      "CaseCollaborationCaseNoteReply": {
        "type": "object",
        "properties": {
          "uuid": {
            "type": "string",
            "format": "uuid"
          },
          "actor_name": {
            "type": "string",
            "nullable": true
          },
          "actor_email": {
            "type": "string",
            "format": "email",
            "nullable": true
          },
          "comment": {
            "type": "string",
            "maxLength": 300
          }
        },
        "required": [
          "actor_email",
          "actor_name",
          "comment",
          "uuid"
        ]
      },
      "FraudCheckModuleReport": {
        "type": "object",
        "properties": {
          "module": {
            "$ref": "#/components/schemas/FraudExcludeEnum"
          },
          "status": {
            "$ref": "#/components/schemas/FraudStatusEnum"
          },
          "reason": {
            "type": "string",
            "nullable": true
          },
          "latency_ms": {
            "type": "integer"
          },
          "freshness": {
            "type": "string",
            "nullable": true
          },
          "billable_units": {
            "type": "integer"
          }
        },
        "required": [
          "billable_units",
          "freshness",
          "latency_ms",
          "module",
          "reason",
          "status"
        ]
      },
      "CaseDuplicateEntityTypeEnum": {
        "enum": [
          "session",
          "business_session",
          "transaction"
        ],
        "type": "string",
        "description": "* `session` - Sesi\n* `business_session` - Sesi Bisnis\n* `transaction` - Transaksi"
      },
      "FraudClientCredentialsErrorMessage": {
        "type": "object",
        "properties": {
          "detail": {
            "type": "string",
            "default": "Authentication failed: Invalid client access token."
          }
        }
      },
      "FraudAvailabilityEnum": {
        "enum": [
          "available",
          "not_requested",
          "no_reference",
          "insufficient_history",
          "unsupported_region",
          "source_unavailable"
        ],
        "type": "string",
        "description": "* `available` - Tersedia\n* `not_requested` - Tidak Diminta\n* `no_reference` - Tidak Ada Referensi\n* `insufficient_history` - Riwayat Tidak Cukup\n* `unsupported_region` - Wilayah Tidak Didukung\n* `source_unavailable` - Sumber Tidak Tersedia"
      },
      "CasePublicationPolicyDraftResponse": {
        "type": "object",
        "properties": {
          "draft": {
            "allOf": [
              {
                "$ref": "#/components/schemas/CasePublicationPolicyDraft"
              }
            ],
            "nullable": true
          }
        },
        "required": [
          "draft"
        ]
      },
      "FraudCheckAttributesRequest": {
        "type": "object",
        "description": "Atribut pendukung. Semua bersifat opsional; atribut ini memperluas cakupan modul.",
        "properties": {
          "first_name": {
            "type": "string",
            "maxLength": 128
          },
          "last_name": {
            "type": "string",
            "maxLength": 128
          },
          "full_name": {
            "type": "string",
            "maxLength": 256
          },
          "date_of_birth": {
            "type": "string",
            "format": "date"
          },
          "nationality": {
            "type": "string",
            "maxLength": 3
          },
          "gender": {
            "type": "string",
            "maxLength": 16
          },
          "address": {
            "type": "string",
            "maxLength": 512
          },
          "city": {
            "type": "string",
            "maxLength": 128
          },
          "state": {
            "type": "string",
            "maxLength": 128
          },
          "postal_code": {
            "type": "string",
            "maxLength": 32
          }
        }
      },
      "NetworkNote": {
        "type": "object",
        "required": [
          "uuid",
          "actor_email",
          "comment",
          "client_reference",
          "created_at"
        ],
        "properties": {
          "uuid": {
            "type": "string",
            "format": "uuid",
            "readOnly": true
          },
          "actor_email": {
            "type": "string",
            "format": "email",
            "readOnly": true,
            "description": "Penulis terautentikasi, ditetapkan oleh server."
          },
          "comment": {
            "type": "string",
            "minLength": 1,
            "maxLength": 10000
          },
          "client_reference": {
            "type": "string",
            "format": "uuid"
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "readOnly": true
          }
        }
      },
      "CaseActionEntityTypeEnum": {
        "enum": [
          "user",
          "business"
        ],
        "type": "string",
        "description": "* `user` - user\n* `business` - business"
      },
      "CaseRoutingCondition": {
        "type": "object",
        "properties": {
          "field": {
            "type": "string",
            "enum": [
              "source",
              "priority",
              "tags"
            ]
          },
          "operator": {
            "type": "string",
            "enum": [
              "equals",
              "in",
              "contains"
            ]
          },
          "value": {
            "oneOf": [
              {
                "type": "string"
              },
              {
                "type": "array",
                "items": {
                  "type": "string"
                }
              }
            ]
          }
        },
        "required": [
          "field",
          "operator",
          "value"
        ],
        "description": "Sumber dan prioritas mendukung equals atau in dengan nilai yang didukung. Tag mendukung contains dengan satu tag yang tidak kosong."
      },
      "RoutingPublicationPolicyRevision": {
        "type": "object",
        "properties": {
          "version": {
            "type": "integer",
            "maximum": 2147483647,
            "minimum": 0
          },
          "snapshot": {},
          "actor_email": {
            "type": "string",
            "format": "email",
            "nullable": true,
            "maxLength": 254
          },
          "published_at": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "published_at",
          "snapshot",
          "version"
        ]
      },
      "CasePublicationPolicyRevision": {
        "type": "object",
        "properties": {
          "version": {
            "type": "integer",
            "maximum": 2147483647,
            "minimum": 0
          },
          "snapshot": {},
          "actor_email": {
            "type": "string",
            "format": "email",
            "nullable": true,
            "maxLength": 254
          },
          "published_at": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "published_at",
          "snapshot",
          "version"
        ]
      },
      "FraudCheckIdentityRelationship": {
        "type": "object",
        "properties": {
          "result": {
            "$ref": "#/components/schemas/FraudResultEnum"
          },
          "reference_type": {
            "type": "string"
          },
          "country": {
            "type": "string"
          },
          "availability": {
            "$ref": "#/components/schemas/FraudAvailabilityEnum"
          },
          "reason_codes": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "required": [
          "availability",
          "country",
          "reason_codes",
          "reference_type",
          "result"
        ]
      },
      "CasePublicationPaginatedPolicyRevisionList": {
        "type": "object",
        "required": [
          "count",
          "results"
        ],
        "properties": {
          "count": {
            "type": "integer",
            "example": 123
          },
          "next": {
            "type": "string",
            "nullable": true,
            "format": "uri",
            "example": "http://api.example.org/accounts/?offset=400&limit=100"
          },
          "previous": {
            "type": "string",
            "nullable": true,
            "format": "uri",
            "example": "http://api.example.org/accounts/?offset=200&limit=100"
          },
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CasePublicationPolicyRevision"
            }
          }
        }
      },
      "CaseDuplicateBlankEnum": {
        "enum": [
          ""
        ]
      },
      "FraudCheckPlan": {
        "type": "object",
        "properties": {
          "profile_id": {
            "type": "string"
          },
          "profile_version": {
            "type": "string"
          },
          "modules": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FraudCheckPlannedModule"
            }
          },
          "estimated_price": {
            "type": "string",
            "nullable": true
          },
          "currency": {
            "type": "string",
            "nullable": true
          },
          "is_sandbox": {
            "type": "boolean"
          },
          "can_afford": {
            "type": "boolean"
          }
        },
        "required": [
          "can_afford",
          "currency",
          "estimated_price",
          "is_sandbox",
          "modules",
          "profile_id",
          "profile_version"
        ]
      },
      "CaseReviewTeamUpdate": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "maxLength": 100
          },
          "description": {
            "type": "string",
            "maxLength": 500
          },
          "members": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CaseReviewTeamMember"
            },
            "maxItems": 250
          },
          "is_active": {
            "type": "boolean"
          }
        }
      },
      "RoutingPublicationPolicyDraft": {
        "type": "object",
        "properties": {
          "revision": {
            "type": "string",
            "format": "uuid"
          },
          "base_version": {
            "type": "integer",
            "maximum": 2147483647,
            "minimum": 0
          },
          "changes": {},
          "actor_email": {
            "type": "string",
            "format": "email",
            "nullable": true,
            "maxLength": 254
          },
          "updated_at": {
            "type": "string",
            "format": "date-time",
            "readOnly": true
          }
        },
        "required": [
          "base_version",
          "updated_at"
        ]
      },
      "FraudCheckRequestRequest": {
        "type": "object",
        "properties": {
          "client_reference": {
            "type": "string",
            "minLength": 1,
            "description": "Referensi Anda sendiri untuk pemeriksaan ini. Berfungsi ganda sebagai kunci idempotensi: menggunakannya kembali dengan isi permintaan yang sama akan mengembalikan pemeriksaan asli tanpa menjalankan atau menagih modul lagi; menggunakannya kembali dengan isi permintaan yang berbeda akan mengembalikan 409.",
            "maxLength": 255
          },
          "profile": {
            "type": "string",
            "minLength": 1,
            "default": "standard",
            "description": "ID profil orkestrasi. Default ke profil `standard` Didit.",
            "maxLength": 64
          },
          "profile_version": {
            "type": "string",
            "minLength": 1,
            "description": "Sematkan versi profil yang dibekukan. Secara default menggunakan versi profil saat ini.",
            "maxLength": 32
          },
          "subject": {
            "$ref": "#/components/schemas/FraudCheckSubjectRequest"
          },
          "context": {
            "$ref": "#/components/schemas/FraudCheckContextRequest"
          },
          "checks": {
            "$ref": "#/components/schemas/FraudCheckModuleSelectionRequest"
          },
          "vendor_data": {
            "type": "string",
            "maxLength": 1000
          },
          "metadata": {}
        },
        "required": [
          "subject"
        ]
      },
      "CaseDuplicateCaseSubjectInputRequest": {
        "type": "object",
        "properties": {
          "type": {
            "$ref": "#/components/schemas/CaseDuplicateTypeEnum"
          },
          "uuid": {
            "type": "string",
            "format": "uuid"
          }
        },
        "required": [
          "type",
          "uuid"
        ]
      },
      "CaseReviewTeamMember": {
        "type": "object",
        "properties": {
          "user_id": {
            "type": "string",
            "format": "uuid"
          },
          "availability": {
            "type": "string",
            "enum": [
              "available",
              "unavailable"
            ],
            "default": "available"
          },
          "capacity": {
            "type": "integer",
            "minimum": 1,
            "maximum": 1000,
            "default": 10
          },
          "skills": {
            "type": "array",
            "items": {
              "type": "string",
              "maxLength": 64
            },
            "maxItems": 25
          },
          "available_from": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "available_until": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          }
        },
        "required": [
          "user_id"
        ]
      },
      "CaseRoutingPreviewRequest": {
        "type": "object",
        "properties": {
          "source": {
            "type": "string",
            "enum": [
              "MANUAL",
              "AML_SCREENING",
              "TRANSACTION_RULE",
              "WORKFLOW_BUILDER"
            ]
          },
          "priority": {
            "type": "string",
            "enum": [
              "LOW",
              "MEDIUM",
              "HIGH"
            ],
            "default": "MEDIUM"
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "string",
              "maxLength": 64
            },
            "maxItems": 50
          },
          "rule_uuid": {
            "type": "string",
            "format": "uuid"
          },
          "draft": {
            "$ref": "#/components/schemas/CaseRoutingRuleCreate"
          }
        },
        "required": [
          "source"
        ]
      },
      "FraudExcludeEnum": {
        "enum": [
          "normalization",
          "email_risk",
          "email_social",
          "phone_social",
          "phone_risk",
          "ip_risk",
          "database_validation",
          "networks_same_org",
          "networks_cross_org",
          "biometric_identity"
        ],
        "type": "string",
        "description": "* `normalization` - Normalisasi\n* `email_risk` - Risiko Email\n* `email_social` - Sosial Email\n* `phone_social` - Sosial Telepon\n* `phone_risk` - Risiko Telepon\n* `ip_risk` - Risiko IP\n* `database_validation` - Validasi Database\n* `networks_same_org` - Jaringan Organisasi Sama\n* `networks_cross_org` - Jaringan Lintas Organisasi\n* `biometric_identity` - Identitas Biometrik"
      },
      "CaseDuplicateCaseLinkCreateRequest": {
        "type": "object",
        "properties": {
          "entity_type": {
            "$ref": "#/components/schemas/CaseDuplicateEntityTypeEnum"
          },
          "entity_uuid": {
            "type": "string",
            "format": "uuid"
          }
        },
        "required": [
          "entity_type",
          "entity_uuid"
        ]
      },
      "CaseDuplicateStatusEnum": {
        "enum": [
          "OPEN",
          "AWAITING_USER",
          "RESOLVED"
        ],
        "type": "string",
        "description": "* `OPEN` - Terbuka\n* `AWAITING_USER` - Menunggu pengguna\n* `RESOLVED` - Diselesaikan"
      },
      "FraudBandEnum": {
        "enum": [
          "low",
          "medium",
          "high",
          "unknown"
        ],
        "type": "string",
        "description": "* `low` - Rendah\n* `medium` - Sedang\n* `high` - Tinggi\n* `unknown` - Tidak Diketahui"
      },
      "CaseDuplicatePriorityEnum": {
        "enum": [
          "LOW",
          "MEDIUM",
          "HIGH"
        ],
        "type": "string",
        "description": "* `LOW` - Rendah\n* `MEDIUM` - Sedang\n* `HIGH` - Tinggi"
      },
      "FraudStatusEnum": {
        "enum": [
          "planned",
          "completed",
          "skipped",
          "failed"
        ],
        "type": "string",
        "description": "* `planned` - Direncanakan\n* `completed` - Selesai\n* `skipped` - Dilewati\n* `failed` - Gagal"
      },
      "FraudCheckInput": {
        "type": "object",
        "properties": {
          "reference": {
            "type": "string",
            "description": "Handle yang disunting untuk pengidentifikasi yang dikirimkan."
          },
          "type": {
            "$ref": "#/components/schemas/FraudTypeEnum"
          },
          "namespace": {
            "type": "object",
            "additionalProperties": {}
          },
          "quality": {
            "type": "string"
          },
          "normalization": {
            "type": "object",
            "additionalProperties": {}
          },
          "availability": {
            "$ref": "#/components/schemas/FraudAvailabilityEnum"
          }
        },
        "required": [
          "availability",
          "namespace",
          "normalization",
          "quality",
          "reference",
          "type"
        ]
      },
      "CustomerMessagingPurposesEnum": {
        "enum": [
          "identity_document",
          "proof_of_address",
          "business_document",
          "confirm_details",
          "review_in_progress"
        ],
        "type": "string",
        "description": "* `identity_document` - identity_document\n* `proof_of_address` - proof_of_address\n* `business_document` - business_document\n* `confirm_details` - confirm_details\n* `review_in_progress` - review_in_progress"
      },
      "FraudTypeEnum": {
        "enum": [
          "email",
          "phone",
          "national_id",
          "tax_number",
          "passport_number",
          "driving_licence_number",
          "residence_permit_number",
          "voter_id",
          "external_id"
        ],
        "type": "string",
        "description": "* `email` - Email\n* `phone` - Telepon\n* `national_id` - ID Nasional\n* `tax_number` - Nomor Pajak\n* `passport_number` - Nomor Paspor\n* `driving_licence_number` - Nomor SIM\n* `residence_permit_number` - Nomor Izin Tinggal\n* `voter_id` - ID Pemilih\n* `external_id` - ID Eksternal"
      },
      "CaseDuplicateCaseSubjectInput": {
        "type": "object",
        "properties": {
          "type": {
            "$ref": "#/components/schemas/CaseDuplicateTypeEnum"
          },
          "uuid": {
            "type": "string",
            "format": "uuid"
          }
        },
        "required": [
          "type",
          "uuid"
        ]
      },
      "CaseReviewTeamCreate": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "maxLength": 100
          },
          "description": {
            "type": "string",
            "maxLength": 500
          },
          "members": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CaseReviewTeamMember"
            },
            "maxItems": 250
          },
          "is_active": {
            "type": "boolean"
          }
        },
        "required": [
          "name",
          "members"
        ]
      },
      "CaseDuplicateCaseDuplicateQueryRequest": {
        "type": "object",
        "properties": {
          "subject": {
            "$ref": "#/components/schemas/CaseDuplicateCaseSubjectInputRequest"
          },
          "links": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CaseDuplicateCaseLinkCreateRequest"
            }
          },
          "offset": {
            "type": "integer",
            "maximum": 1000000,
            "minimum": 0,
            "default": 0
          }
        }
      },
      "CaseDuplicateResolutionEnum": {
        "enum": [
          "FALSE_POSITIVE",
          "VALID_THREAT"
        ],
        "type": "string",
        "description": "* `FALSE_POSITIVE` - Positif palsu\n* `VALID_THREAT` - Ancaman valid"
      },
      "CasePublicationPolicyDraftWriteRequest": {
        "type": "object",
        "properties": {
          "expected_version": {
            "type": "integer",
            "minimum": 0
          },
          "expected_revision": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "changes": {
            "type": "object",
            "additionalProperties": {}
          }
        },
        "required": [
          "changes",
          "expected_revision",
          "expected_version"
        ]
      },
      "FraudCheckSubjectRequest": {
        "type": "object",
        "properties": {
          "selfie": {
            "type": "string",
            "minLength": 1,
            "description": "Swafoto Base64 JPEG, PNG, atau WebP, hingga 6 MB. Tanpa gambar referensi atau URL.",
            "maxLength": 8388672
          },
          "identifiers": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FraudCheckIdentifierRequest"
            },
            "description": "Satu atau lebih pengenal bertipe. Satu saja sudah cukup.",
            "maxItems": 10,
            "minItems": 1
          },
          "attributes": {
            "$ref": "#/components/schemas/FraudCheckAttributesRequest"
          }
        },
        "required": [
          "identifiers"
        ]
      },
      "RoutingPublicationRoutingCondition": {
        "type": "object",
        "properties": {
          "field": {
            "$ref": "#/components/schemas/RoutingPublicationFieldEnum"
          },
          "operator": {
            "$ref": "#/components/schemas/RoutingPublicationOperatorEnum"
          },
          "value": {}
        },
        "required": [
          "field",
          "operator",
          "value"
        ]
      },
      "CaseActionCaseActionReceipt": {
        "type": "object",
        "properties": {
          "uuid": {
            "type": "string",
            "format": "uuid",
            "readOnly": true
          },
          "client_reference": {
            "type": "string",
            "format": "uuid"
          },
          "action": {
            "type": "string",
            "maxLength": 32
          },
          "status": {
            "$ref": "#/components/schemas/CaseActionStatusEnum"
          },
          "result": {},
          "error": {
            "type": "string",
            "maxLength": 255
          },
          "actor_email": {
            "type": "string",
            "format": "email",
            "nullable": true,
            "maxLength": 254
          },
          "attempts": {
            "type": "integer",
            "maximum": 2147483647,
            "minimum": 0
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "readOnly": true
          },
          "updated_at": {
            "type": "string",
            "format": "date-time",
            "readOnly": true
          }
        },
        "required": [
          "action",
          "client_reference",
          "created_at",
          "status",
          "updated_at",
          "uuid"
        ]
      },
      "FraudCheckContextRequest": {
        "type": "object",
        "properties": {
          "ip_address": {
            "type": "string",
            "minLength": 1
          },
          "user_agent": {
            "type": "string",
            "maxLength": 512
          },
          "country": {
            "type": "string",
            "description": "Negara tempat subjek mengaku berada. Hanya kontekstual - tidak pernah menjadi bukti kepemilikan identitas.",
            "maxLength": 3
          },
          "purpose": {
            "type": "string",
            "maxLength": 128
          },
          "consent_obtained": {
            "type": "boolean"
          }
        }
      },
      "CustomerMessagingCaseCustomerResponseResult": {
        "type": "object",
        "properties": {
          "responded_at": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "responded_at"
        ]
      },
      "CustomerMessagingCaseRequestContact": {
        "type": "object",
        "properties": {
          "uuid": {
            "type": "string",
            "format": "uuid"
          },
          "email": {
            "type": "string",
            "format": "email"
          },
          "verified_at": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "email",
          "uuid",
          "verified_at"
        ]
      },
      "FraudClientCredentialsForbiddenErrorMessage": {
        "type": "object",
        "properties": {
          "detail": {
            "type": "string",
            "default": "Forbidden - User doesn't have permission"
          }
        }
      },
      "CasePublicationAssignmentMethodEnum": {
        "enum": [
          "MANUAL",
          "AUTOMATIC"
        ],
        "type": "string",
        "description": "* `MANUAL` - Manual\n* `AUTOMATIC` - Otomatis"
      },
      "CaseDuplicateNullEnum": {
        "enum": [
          null
        ]
      },
      "CustomerMessagingLanguageEnum": {
        "enum": [
          "en",
          "es",
          "pt"
        ],
        "type": "string",
        "description": "* `en` - en\n* `es` - es\n* `pt` - pt"
      },
      "CaseDuplicateCaseFraudSourceContextRequest": {
        "type": "object",
        "properties": {
          "check_id": {
            "type": "string",
            "format": "uuid"
          },
          "request_id": {
            "type": "string",
            "format": "uuid"
          },
          "source_section": {
            "type": "string",
            "minLength": 1,
            "pattern": "^[A-Z][A-Z0-9_:-]{0,63}$"
          }
        },
        "required": [
          "check_id",
          "request_id",
          "source_section"
        ]
      },
      "FraudCheckPlannedModule": {
        "type": "object",
        "properties": {
          "module": {
            "$ref": "#/components/schemas/FraudExcludeEnum"
          },
          "available": {
            "type": "boolean"
          },
          "availability_reason": {
            "type": "string",
            "nullable": true
          },
          "will_run": {
            "type": "boolean"
          },
          "selection_reason": {
            "type": "string",
            "nullable": true
          },
          "estimated_price": {
            "type": "string",
            "nullable": true
          }
        },
        "required": [
          "availability_reason",
          "available",
          "estimated_price",
          "module",
          "selection_reason",
          "will_run"
        ]
      },
      "CustomerMessagingCaseRequestOptions": {
        "type": "object",
        "properties": {
          "contacts": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CustomerMessagingCaseRequestContact"
            }
          },
          "purposes": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CustomerMessagingPurposesEnum"
            }
          },
          "languages": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CustomerMessagingLanguagesEnum"
            }
          }
        },
        "required": [
          "contacts",
          "languages",
          "purposes"
        ]
      },
      "CaseCollaborationPaginatedCaseNoteList": {
        "type": "object",
        "required": [
          "count",
          "results"
        ],
        "properties": {
          "count": {
            "type": "integer",
            "example": 123
          },
          "next": {
            "type": "string",
            "nullable": true,
            "format": "uri",
            "example": "http://api.example.org/accounts/?offset=400&limit=100"
          },
          "previous": {
            "type": "string",
            "nullable": true,
            "format": "uri",
            "example": "http://api.example.org/accounts/?offset=200&limit=100"
          },
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CaseCollaborationCaseNote"
            }
          }
        }
      },
      "FraudProcessingStatusEnum": {
        "enum": [
          "pending",
          "running",
          "completed",
          "failed"
        ],
        "type": "string",
        "description": "* `pending` - Tertunda\n* `running` - Berjalan\n* `completed` - Selesai\n* `failed` - Gagal"
      },
      "CasePublicationCaseBlueprint": {
        "type": "object",
        "properties": {
          "uuid": {
            "type": "string",
            "format": "uuid",
            "readOnly": true
          },
          "name": {
            "type": "string",
            "maxLength": 24
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "assignment_method": {
            "$ref": "#/components/schemas/CasePublicationAssignmentMethodEnum"
          },
          "assignee_pool": {},
          "max_active_cases": {
            "type": "integer",
            "maximum": 2147483647,
            "minimum": 0,
            "nullable": true
          },
          "escalation_enabled": {
            "type": "boolean"
          },
          "escalation_blueprint": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "escalation_blueprint_name": {
            "type": "string",
            "readOnly": true
          },
          "transfer_enabled": {
            "type": "boolean"
          },
          "four_eyes_checker_blueprint": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "four_eyes_checker_blueprint_name": {
            "type": "string",
            "readOnly": true
          },
          "require_resolution_note": {
            "type": "boolean"
          },
          "content_config": {},
          "version": {
            "type": "integer",
            "maximum": 2147483647,
            "minimum": 0
          },
          "default_deadline_hours": {
            "type": "integer",
            "maximum": 2147483647,
            "minimum": 0,
            "nullable": true
          },
          "is_active": {
            "type": "boolean"
          },
          "preset_key": {
            "type": "string",
            "nullable": true,
            "maxLength": 64
          },
          "creation_sources": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": {}
            },
            "readOnly": true
          },
          "receives_escalation_from": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": {}
            },
            "readOnly": true
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "readOnly": true
          },
          "updated_at": {
            "type": "string",
            "format": "date-time",
            "readOnly": true
          }
        },
        "required": [
          "created_at",
          "creation_sources",
          "escalation_blueprint_name",
          "four_eyes_checker_blueprint_name",
          "name",
          "receives_escalation_from",
          "updated_at",
          "uuid"
        ]
      },
      "CaseRoutingRuleUpdate": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "maxLength": 100
          },
          "description": {
            "type": "string",
            "maxLength": 500
          },
          "priority": {
            "type": "integer",
            "minimum": 0
          },
          "conditions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CaseRoutingCondition"
            },
            "maxItems": 20
          },
          "required_skills": {
            "type": "array",
            "items": {
              "type": "string",
              "maxLength": 64
            },
            "maxItems": 25
          },
          "blueprint": {
            "type": "string",
            "format": "uuid"
          },
          "team": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "is_active": {
            "type": "boolean"
          },
          "expected_version": {
            "type": "integer",
            "minimum": 1,
            "writeOnly": true,
            "description": "Versi yang dibuka oleh editor. Jika diberikan, penulisan yang usang akan mengembalikan 409 tanpa mengubah aturan."
          }
        }
      },
      "CustomerMessagingCaseRequestPreviewRequest": {
        "type": "object",
        "properties": {
          "contact_id": {
            "type": "string",
            "format": "uuid"
          },
          "purpose": {
            "$ref": "#/components/schemas/CustomerMessagingPurposeEnum"
          },
          "language": {
            "allOf": [
              {
                "$ref": "#/components/schemas/CustomerMessagingLanguageEnum"
              }
            ],
            "default": "en"
          }
        },
        "required": [
          "contact_id",
          "purpose"
        ]
      },
      "CaseDuplicateCaseFraudSourceContext": {
        "type": "object",
        "properties": {
          "check_id": {
            "type": "string",
            "format": "uuid"
          },
          "request_id": {
            "type": "string",
            "format": "uuid"
          },
          "source_section": {
            "type": "string",
            "pattern": "^[A-Z][A-Z0-9_:-]{0,63}$"
          }
        },
        "required": [
          "check_id",
          "request_id",
          "source_section"
        ]
      },
      "RoutingPublicationOperatorEnum": {
        "enum": [
          "equals",
          "in",
          "contains"
        ],
        "type": "string",
        "description": "* `equals` - sama dengan\n* `in` - di dalam\n* `contains` - berisi"
      },
      "CaseRoutingPreview": {
        "type": "object",
        "properties": {
          "rule_uuid": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "rule_name": {
            "type": "string",
            "nullable": true
          },
          "rule_version": {
            "type": "integer",
            "nullable": true
          },
          "blueprint_uuid": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "team_uuid": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "assignee_user_id": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "reason": {
            "type": "string"
          },
          "candidates": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "user_id": {
                  "type": "string",
                  "format": "uuid"
                },
                "eligible": {
                  "type": "boolean"
                },
                "active_cases": {
                  "type": "integer",
                  "nullable": true
                },
                "reason": {
                  "type": "string",
                  "nullable": true
                }
              }
            }
          },
          "matched_rules": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "uuid": {
                  "type": "string",
                  "format": "uuid"
                },
                "name": {
                  "type": "string"
                },
                "priority": {
                  "type": "integer"
                }
              }
            }
          }
        }
      },
      "FraudDimensionEnum": {
        "enum": [
          "identity",
          "contact",
          "device_network",
          "behavioral",
          "fraud_network"
        ],
        "type": "string",
        "description": "* `identity` - Identitas\n* `contact` - Kontak\n* `device_network` - Jaringan Perangkat\n* `behavioral` - Perilaku\n* `fraud_network` - Jaringan Penipuan"
      },
      "FraudBadRequestErrorMessage": {
        "type": "object",
        "properties": {
          "detail": {
            "type": "string",
            "default": "Bad Request - Invalid request data"
          }
        }
      },
      "FraudNextActionEnum": {
        "enum": [
          "none",
          "manual_review",
          "step_up",
          "resubmit_capture"
        ],
        "type": "string",
        "description": "* `none` - Tidak Ada\n* `manual_review` - Peninjauan Manual\n* `step_up` - Peningkatan Verifikasi\n* `resubmit_capture` - Kirim Ulang Pengambilan"
      },
      "RoutingPublicationPolicyDraftPreconditionRequest": {
        "type": "object",
        "properties": {
          "expected_version": {
            "type": "integer",
            "minimum": 0
          },
          "expected_revision": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          }
        },
        "required": [
          "expected_revision",
          "expected_version"
        ]
      },
      "FraudCheckRisk": {
        "type": "object",
        "properties": {
          "dimension": {
            "$ref": "#/components/schemas/FraudDimensionEnum"
          },
          "score": {
            "type": "integer",
            "nullable": true
          },
          "band": {
            "$ref": "#/components/schemas/FraudBandEnum"
          },
          "availability": {
            "$ref": "#/components/schemas/FraudAvailabilityEnum"
          },
          "requested_but_unavailable": {
            "type": "boolean",
            "description": "True saat permintaan menyediakan semua yang dibutuhkan dimensi ini dan platform tetap tidak dapat menjawabnya. Pemeriksaan semacam itu tidak pernah direkomendasikan untuk disetujui hanya berdasarkan dimensi yang berhasil dijawab."
          },
          "reason_codes": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "evidence_indexes": {
            "type": "array",
            "items": {
              "type": "integer"
            }
          }
        },
        "required": [
          "availability",
          "band",
          "dimension",
          "evidence_indexes",
          "reason_codes",
          "requested_but_unavailable",
          "score"
        ]
      },
      "CaseDuplicateSourceEnum": {
        "enum": [
          "MANUAL",
          "AML_SCREENING",
          "TRANSACTION_RULE",
          "WORKFLOW_BUILDER"
        ],
        "type": "string",
        "description": "* `MANUAL` - Manual\n* `AML_SCREENING` - Skrining AML\n* `TRANSACTION_RULE` - Aturan transaksi\n* `WORKFLOW_BUILDER` - Pembangun alur kerja"
      },
      "CaseCollaborationPatchedCaseNoteUpdateRequest": {
        "type": "object",
        "properties": {
          "is_pinned": {
            "type": "boolean"
          }
        }
      },
      "CustomerMessagingPurposeEnum": {
        "enum": [
          "identity_document",
          "proof_of_address",
          "business_document",
          "confirm_details",
          "review_in_progress"
        ],
        "type": "string",
        "description": "* `identity_document` - identity_document\n* `proof_of_address` - proof_of_address\n* `business_document` - business_document\n* `confirm_details` - confirm_details\n* `review_in_progress` - review_in_progress"
      },
      "CaseDuplicateTypeEnum": {
        "enum": [
          "user",
          "business"
        ],
        "type": "string",
        "description": "* `user` - user\n* `business` - business"
      },
      "CaseCollaborationCaseNoteCreateRequest": {
        "type": "object",
        "properties": {
          "comment": {
            "type": "string",
            "minLength": 1,
            "maxLength": 10000
          },
          "reply_to": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "client_reference": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "mentioned_emails": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "email",
              "minLength": 1
            }
          },
          "is_internal": {
            "type": "boolean",
            "default": false
          },
          "attachments": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": {}
            }
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "string",
              "minLength": 1
            }
          }
        },
        "required": [
          "comment"
        ]
      },
      "CustomerMessagingLanguagesEnum": {
        "enum": [
          "en",
          "es",
          "pt"
        ],
        "type": "string",
        "description": "* `en` - en\n* `es` - es\n* `pt` - pt"
      },
      "CustomerMessagingCaseRequestConfirmRequest": {
        "type": "object",
        "properties": {
          "contact_id": {
            "type": "string",
            "format": "uuid"
          },
          "purpose": {
            "$ref": "#/components/schemas/CustomerMessagingPurposeEnum"
          },
          "language": {
            "allOf": [
              {
                "$ref": "#/components/schemas/CustomerMessagingLanguageEnum"
              }
            ],
            "default": "en"
          },
          "request_id": {
            "type": "string",
            "format": "uuid"
          },
          "expires_at": {
            "type": "string",
            "format": "date-time"
          },
          "preview_token": {
            "type": "string",
            "minLength": 1,
            "maxLength": 512
          }
        },
        "required": [
          "contact_id",
          "expires_at",
          "preview_token",
          "purpose",
          "request_id"
        ]
      },
      "CaseRoutingRule": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "maxLength": 100
          },
          "description": {
            "type": "string",
            "maxLength": 500
          },
          "priority": {
            "type": "integer",
            "minimum": 0
          },
          "conditions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CaseRoutingCondition"
            },
            "maxItems": 20
          },
          "required_skills": {
            "type": "array",
            "items": {
              "type": "string",
              "maxLength": 64
            },
            "maxItems": 25
          },
          "blueprint": {
            "type": "string",
            "format": "uuid"
          },
          "team": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "is_active": {
            "type": "boolean"
          },
          "uuid": {
            "type": "string",
            "format": "uuid",
            "readOnly": true
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "readOnly": true
          },
          "updated_at": {
            "type": "string",
            "format": "date-time",
            "readOnly": true
          },
          "version": {
            "type": "integer",
            "readOnly": true
          },
          "blueprint_name": {
            "type": "string",
            "readOnly": true
          },
          "team_name": {
            "type": "string",
            "nullable": true,
            "readOnly": true
          }
        }
      },
      "FraudResultEnum": {
        "enum": [
          "match",
          "mismatch",
          "inconclusive",
          "no_reference"
        ],
        "type": "string",
        "description": "* `match` - Cocok\n* `mismatch` - Tidak Cocok\n* `inconclusive` - Tidak Konklusif\n* `no_reference` - Tidak Ada Referensi"
      },
      "CaseRoutingRuleCreate": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "maxLength": 100
          },
          "description": {
            "type": "string",
            "maxLength": 500
          },
          "priority": {
            "type": "integer",
            "minimum": 0
          },
          "conditions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CaseRoutingCondition"
            },
            "maxItems": 20
          },
          "required_skills": {
            "type": "array",
            "items": {
              "type": "string",
              "maxLength": 64
            },
            "maxItems": 25
          },
          "blueprint": {
            "type": "string",
            "format": "uuid"
          },
          "team": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "is_active": {
            "type": "boolean"
          },
          "publish": {
            "type": "boolean",
            "writeOnly": true,
            "description": "Setel ke false untuk menyimpan draf yang belum pernah dipublikasikan. Rekaman tetap tidak aktif pada versi 0 hingga draf tersebut dipublikasikan secara eksplisit. Menghilangkan kolom ini mempertahankan pembuatan langsung untuk integrasi yang ada."
          }
        },
        "required": [
          "name",
          "conditions",
          "blueprint"
        ]
      },
      "FraudCheckIdentifierRequest": {
        "type": "object",
        "properties": {
          "type": {
            "allOf": [
              {
                "$ref": "#/components/schemas/FraudTypeEnum"
              }
            ],
            "description": "Tipe pengenal. Menentukan kolom namespace mana yang wajib diisi.\n\n* `email` - Email\n* `phone` - Telepon\n* `national_id` - ID Nasional\n* `tax_number` - Nomor Pajak\n* `passport_number` - Nomor Paspor\n* `driving_licence_number` - Nomor SIM\n* `residence_permit_number` - Nomor Izin Tinggal\n* `voter_id` - ID Pemilih\n* `external_id` - ID Eksternal"
          },
          "value": {
            "type": "string",
            "minLength": 1,
            "description": "Nilai pengidentifikasi, dalam format umum apa pun.",
            "maxLength": 255
          },
          "country": {
            "type": "string",
            "description": "Negara penerbit ISO-3166 alpha-2 atau alpha-3. Wajib untuk tipe pengenal pemerintah: digit yang sama mewakili orang yang berbeda di negara yang berbeda.",
            "maxLength": 3
          },
          "issuer": {
            "type": "string",
            "description": "Otoritas penerbit atau penerbit sub-nasional opsional, jika negara saja tidak unik.",
            "maxLength": 128
          }
        },
        "required": [
          "type",
          "value"
        ]
      },
      "CaseActionActionEnum": {
        "enum": [
          "set_status",
          "add_tags",
          "add_note",
          "add_to_blocklist"
        ],
        "type": "string",
        "description": "* `set_status` - set_status\n* `add_tags` - add_tags\n* `add_note` - add_note\n* `add_to_blocklist` - add_to_blocklist"
      },
      "CaseActionCaseActionReceiptPage": {
        "type": "object",
        "properties": {
          "count": {
            "type": "integer"
          },
          "next_offset": {
            "type": "integer",
            "nullable": true
          },
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CaseActionCaseActionReceipt"
            }
          }
        },
        "required": [
          "count",
          "next_offset",
          "results"
        ]
      },
      "CaseActionCaseEntityActionResult": {
        "type": "object",
        "properties": {
          "receipt": {
            "$ref": "#/components/schemas/CaseActionCaseActionReceipt"
          },
          "entity_type": {
            "$ref": "#/components/schemas/CaseActionEntityTypeEnum"
          },
          "entity_uuid": {
            "type": "string",
            "format": "uuid"
          },
          "action": {
            "type": "string"
          },
          "previous_status": {
            "type": "string"
          },
          "new_status": {
            "type": "string"
          },
          "tags_added": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "comment_uuid": {
            "type": "string",
            "format": "uuid"
          },
          "blocklisted": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        }
      },
      "CustomerMessagingCaseRequest": {
        "type": "object",
        "properties": {
          "uuid": {
            "type": "string",
            "format": "uuid",
            "readOnly": true
          },
          "purpose": {
            "type": "string",
            "readOnly": true
          },
          "language": {
            "type": "string",
            "readOnly": true
          },
          "recipient": {
            "type": "string",
            "format": "email",
            "readOnly": true
          },
          "expires_at": {
            "type": "string",
            "format": "date-time",
            "readOnly": true
          },
          "actor_email": {
            "type": "string",
            "format": "email",
            "readOnly": true,
            "nullable": true
          },
          "delivery_status": {
            "type": "string",
            "readOnly": true
          },
          "delivered_at": {
            "type": "string",
            "format": "date-time",
            "readOnly": true,
            "nullable": true
          },
          "cancelled_at": {
            "type": "string",
            "format": "date-time",
            "readOnly": true,
            "nullable": true
          },
          "responded_at": {
            "type": "string",
            "format": "date-time",
            "readOnly": true,
            "nullable": true
          },
          "response": {
            "readOnly": true,
            "nullable": true
          },
          "has_attachment": {
            "type": "boolean",
            "readOnly": true
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "readOnly": true
          }
        },
        "required": [
          "actor_email",
          "cancelled_at",
          "created_at",
          "delivered_at",
          "delivery_status",
          "expires_at",
          "has_attachment",
          "language",
          "purpose",
          "recipient",
          "responded_at",
          "response",
          "uuid"
        ]
      },
      "CustomerMessagingCaseRequestPublic": {
        "type": "object",
        "properties": {
          "request_id": {
            "type": "string",
            "format": "uuid"
          },
          "purpose": {
            "$ref": "#/components/schemas/CustomerMessagingPurposeEnum"
          },
          "language": {
            "$ref": "#/components/schemas/CustomerMessagingLanguageEnum"
          },
          "expires_at": {
            "type": "string",
            "format": "date-time"
          },
          "responded_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "copy": {
            "type": "object",
            "additionalProperties": {}
          },
          "organization_name": {
            "type": "string"
          },
          "is_white_label": {
            "type": "boolean"
          },
          "customization": {
            "type": "object",
            "additionalProperties": {},
            "nullable": true
          }
        },
        "required": [
          "copy",
          "customization",
          "expires_at",
          "is_white_label",
          "language",
          "organization_name",
          "purpose",
          "request_id",
          "responded_at"
        ]
      },
      "RoutingPublicationFieldEnum": {
        "enum": [
          "source",
          "priority",
          "tags"
        ],
        "type": "string",
        "description": "* `source` - source\n* `priority` - priority\n* `tags` - tags"
      },
      "RoutingPublicationCaseRoutingRule": {
        "type": "object",
        "properties": {
          "uuid": {
            "type": "string",
            "format": "uuid",
            "readOnly": true
          },
          "name": {
            "type": "string",
            "maxLength": 100
          },
          "description": {
            "type": "string",
            "maxLength": 500
          },
          "priority": {
            "type": "integer",
            "maximum": 2147483647,
            "minimum": 0
          },
          "conditions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/RoutingPublicationRoutingCondition"
            }
          },
          "required_skills": {
            "type": "array",
            "items": {
              "type": "string",
              "maxLength": 64
            },
            "maxItems": 25
          },
          "blueprint": {
            "type": "string",
            "format": "uuid"
          },
          "blueprint_name": {
            "type": "string",
            "readOnly": true
          },
          "team": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "team_name": {
            "type": "string",
            "readOnly": true
          },
          "is_active": {
            "type": "boolean"
          },
          "version": {
            "type": "integer",
            "readOnly": true
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "readOnly": true
          },
          "updated_at": {
            "type": "string",
            "format": "date-time",
            "readOnly": true
          }
        },
        "required": [
          "blueprint",
          "blueprint_name",
          "conditions",
          "created_at",
          "name",
          "team_name",
          "updated_at",
          "uuid",
          "version"
        ]
      },
      "CaseActionStatusEnum": {
        "enum": [
          "APPLIED",
          "FAILED"
        ],
        "type": "string",
        "description": "* `APPLIED` - Diterapkan\n* `FAILED` - Gagal"
      },
      "FraudCheckModuleSelectionRequest": {
        "type": "object",
        "properties": {
          "include": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FraudExcludeEnum"
            }
          },
          "exclude": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FraudExcludeEnum"
            }
          }
        }
      },
      "SignatureField": {
        "type": "object",
        "description": "Kolom yang akan ditempatkan pada dokumen sesi: penandatangan mana yang mengisinya, bagaimana caranya, dan di mana posisinya. Berikan posisi (`page`, `x`, `y`, `width`, dan `height`) atau sebuah `anchor`. Posisi berupa pecahan dari halaman seperti yang ditampilkan, dari sudut kiri atasnya, dibulatkan ke 4 desimal, dan kolom harus pas di dalam halaman. Sebuah dokumen dapat memuat hingga 200 kolom dan satu penandatangan hingga 500, serta setiap peran dengan kolom pada dokumen memerlukan kolom `signature` atau `initials` di sana. Lihat [Kolom pada dokumen](/id/core-technology/electronic-signature/overview#kolom-pada-dokumen).",
        "required": [
          "key",
          "type"
        ],
        "properties": {
          "key": {
            "type": "string",
            "pattern": "^[a-z][a-z0-9_]{0,63}$",
            "description": "Nama kolom dalam hasil dan dalam `sign.field_values`. Unik di dalam dokumen."
          },
          "type": {
            "type": "string",
            "enum": [
              "signature",
              "initials",
              "full_name",
              "date_signed",
              "text",
              "checkbox",
              "email",
              "data"
            ],
            "description": "Apa yang dimuat oleh kolom ini. Penandatangan menerapkan `signature` dan `initials` yang mereka gunakan, mengetik `text`, mencentang `checkbox`, dan mengetik `email` saat sesi tidak memiliki email terverifikasi. Didit mengisi `full_name` (nama terverifikasi), `date_signed` (tanggal penandatanganan, dalam zona waktu penandatangan), `data` (dari `prefill`), dan `email` terverifikasi, lalu menampilkannya sebagai hanya-baca. Tidak ada jenis pemilih tanggal: gunakan `text`."
          },
          "role": {
            "type": "string",
            "enum": [
              "verified_person",
              "legal_representative",
              "key_people"
            ],
            "description": "Pihak yang mengisi kolom, dengan nilai `signature_signer`. Suatu langkah hanya mengisi dan membubuhkan stempel pada kolom penandatangan miliknya sendiri. Default ke penandatangan langkah tersebut."
          },
          "page": {
            "type": "integer",
            "minimum": 1,
            "description": "Nomor halaman, dari 1 hingga jumlah halaman dokumen. Untuk dokumen Word, halaman dari PDF yang dikonversi."
          },
          "x": {
            "type": "number",
            "minimum": 0,
            "maximum": 1,
            "description": "Tepi kiri, sebagai fraksi dari lebar halaman."
          },
          "y": {
            "type": "number",
            "minimum": 0,
            "maximum": 1,
            "description": "Tepi atas, sebagai fraksi dari tinggi halaman."
          },
          "width": {
            "type": "number",
            "minimum": 0.02,
            "maximum": 1,
            "description": "Lebar, sebagai fraksi dari lebar halaman. Tanda tangan memiliki lebar minimal `0.12`."
          },
          "height": {
            "type": "number",
            "minimum": 0.012,
            "maximum": 1,
            "description": "Tinggi, sebagai fraksi dari tinggi halaman. Tanda tangan memiliki tinggi minimal `0.035`."
          },
          "anchor": {
            "$ref": "#/components/schemas/SignatureFieldAnchor"
          },
          "required": {
            "type": "boolean",
            "description": "`signature` and `initials` are required unless you set `false`. `full_name`, `date_signed` and `data` are always required. The signer can't finish a document until its required fields have a value, and a required checkbox must be ticked."
          },
          "label": {
            "type": "string",
            "minLength": 1,
            "maxLength": 80,
            "description": "Ditampilkan kepada penandatangan dan di dalam hasil. Nilai default diambil dari jenisnya."
          },
          "placeholder": {
            "type": "string",
            "nullable": true,
            "maxLength": 80,
            "description": "Hanya `text` dan `email`."
          },
          "validation": {
            "$ref": "#/components/schemas/SignatureFieldValidation"
          },
          "prefill": {
            "type": "string",
            "nullable": true,
            "description": "Asal nilai: `identity.full_name`, `identity.first_name`, `identity.last_name`, `identity.date_of_birth` (`DD/MM/YYYY`), `identity.nationality`, `identity.document_number`, `identity.document_type`, `identity.issuing_country`, `identity.address`, `contact.email`, `contact.phone`, `company.name`, `company.registration_number`, `company.address`, `company.country` (KYB), `session.vendor_data`, `metadata.<key>` (kunci dari `metadata` sesi), atau `api.<key>` (kunci dari `sign.field_values`). Wajib diisi untuk `data`. `full_name` selalu menggunakan `identity.full_name` dan `email` menggunakan `contact.email`. Nilai kolom `data`, `full_name`, dan `email` terverifikasi ditetapkan saat penandatangan mulai menandatangani."
          },
          "editable_when_prefilled": {
            "type": "boolean",
            "default": false,
            "description": "Hanya `text` dan `email`: penandatangan dapat mengubah nilai yang telah diisi sebelumnya."
          },
          "checked_by_default": {
            "type": "boolean",
            "default": false,
            "description": "Hanya `checkbox`: kotak dimulai dalam keadaan dicentang."
          },
          "date_format": {
            "type": "string",
            "enum": [
              "DD/MM/YYYY",
              "MM/DD/YYYY",
              "YYYY-MM-DD",
              "D MMMM YYYY"
            ],
            "default": "DD/MM/YYYY",
            "description": "Hanya `date_signed`."
          }
        }
      },
      "SessionSignDocument": {
        "type": "object",
        "required": [
          "file_name",
          "content_base64"
        ],
        "properties": {
          "title": {
            "type": "string",
            "minLength": 1,
            "maxLength": 255,
            "description": "Judul yang ditampilkan kepada penandatangan. Defaultnya adalah `file_name`."
          },
          "file_name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 255,
            "description": "Nama file, berakhiran `.pdf` atau `.docx`."
          },
          "content_base64": {
            "type": "string",
            "format": "byte",
            "description": "File, berenkode base64. PDF dapat berukuran hingga 20 MB dan 100 halaman, tanpa kata sandi, skrip, atau file terlampir. File Word (`.docx`) dapat berukuran hingga 20 MB dan dikonversi ke PDF saat permintaan berjalan, maksimal dalam 25 detik; PDF tersebut kemudian memiliki batas yang sama. Hingga 5 file Word per sesi. File Word dengan makro, perubahan terlacak, tautan ke konten eksternal, atau objek yang disematkan akan ditolak dengan `signature_document_not_supported`, dan file yang tidak dapat dikonversi mengembalikan `signature_document_conversion_failed`, masing-masing disertai `reason`."
          },
          "fields": {
            "type": "array",
            "description": "Kolom opsional untuk ditempatkan pada dokumen ini, hingga 200. Halaman dan posisi merujuk ke PDF, atau ke PDF hasil konversi untuk file Word. Tanpa kolom, penandatangan membaca dokumen dan menyetujuinya.",
            "items": {
              "$ref": "#/components/schemas/SignatureField"
            },
            "maxItems": 200
          }
        }
      },
      "SignatureResult": {
        "type": "object",
        "description": "Hasil satu penandatangan untuk satu langkah Tanda Tangan Elektronik. Lihat [laporan Tanda Tangan Elektronik](/id/core-technology/electronic-signature/report-electronic-signature).",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Teruskan sebagai `signature_id` untuk mengunduh bukti penanda tangan ini atau memvalidasi tanda tangan mereka."
          },
          "node_id": {
            "type": "string",
            "description": "Langkah alur kerja yang menghasilkannya."
          },
          "status": {
            "type": "string",
            "enum": [
              "intro",
              "review",
              "code",
              "signing",
              "signed",
              "declined"
            ],
            "description": "Status penandatangan dalam langkah tersebut. Hanya `signed` yang berarti dokumen telah ditandatangani."
          },
          "verdict": {
            "type": "string",
            "enum": [
              "Not Finished",
              "Approved",
              "In Review",
              "Declined"
            ],
            "description": "Hasil langkah. Peringatan menetapkannya melalui aturannya; aturan status kustom berlaku setelahnya."
          },
          "level": {
            "type": "string",
            "enum": [
              "simple",
              "aes",
              "qes"
            ],
            "description": "`simple` (default) atau `aes`. `qes` (Qualified Electronic Signature, QES) adalah add-on yang belum tersedia."
          },
          "format": {
            "type": "string",
            "enum": [
              "pdf",
              "pades"
            ],
            "description": "`pdf` untuk tanda tangan Simple, `pades` untuk Advanced (AES)."
          },
          "profile": {
            "type": "string",
            "nullable": true,
            "description": "`PAdES-B-LT` setelah tanda tangan Advanced (AES) dibuat, jika tidak maka null."
          },
          "signer": {
            "type": "object",
            "properties": {
              "name": {
                "type": "string",
                "nullable": true,
                "description": "Nama penandatangan. Terverifikasi (dari Verifikasi Identitas yang disetujui atau sesi) kecuali pada tingkat Simple tanpa nama sesi yang terverifikasi, di mana nama tersebut merupakan nama yang diketik penandatangan dan tidak diverifikasi."
              },
              "capacity": {
                "type": "string",
                "enum": [
                  "self",
                  "company"
                ]
              },
              "company": {
                "type": "string",
                "nullable": true
              },
              "role": {
                "type": "string",
                "nullable": true,
                "description": "Jabatan pihak kunci, sebagaimana dinyatakan."
              },
              "roles": {
                "type": "array",
                "items": {
                  "type": "string"
                },
                "description": "Peran terstruktur pihak kunci, sebagaimana dinyatakan untuk perusahaan."
              },
              "identity_session_id": {
                "type": "string",
                "format": "uuid",
                "description": "Sesi KYC yang memverifikasi penandatangan."
              }
            }
          },
          "identity_used": {
            "type": "object",
            "description": "Identitas terverifikasi yang menjadi dasar tanda tangan. Kosong untuk tanda tangan sederhana tanpa identitas terverifikasi.",
            "properties": {
              "session_id": {
                "type": "string",
                "format": "uuid"
              },
              "kyc_id": {
                "type": "string",
                "format": "uuid",
                "nullable": true
              },
              "verified": {
                "type": "boolean"
              },
              "expected_name": {
                "type": "string",
                "nullable": true,
                "description": "Nama yang harus cocok dengan penandatangan."
              }
            }
          },
          "certificate": {
            "type": "object",
            "nullable": true,
            "description": "Sertifikat yang digunakan untuk menandatangani dokumen. `null` sampai ditandatangani, dan selalu `null` untuk tanda tangan Simple.",
            "properties": {
              "issuer": {
                "type": "string"
              },
              "issued_to": {
                "type": "string"
              },
              "serial": {
                "type": "string",
                "description": "Nomor seri, heksadesimal."
              },
              "valid_from": {
                "type": "string",
                "format": "date-time"
              },
              "valid_until": {
                "type": "string",
                "format": "date-time"
              }
            }
          },
          "confirmation": {
            "type": "object",
            "properties": {
              "channel": {
                "type": "string",
                "nullable": true,
                "enum": [
                  "email",
                  "sms"
                ],
                "description": "`null` untuk tanda tangan Simple, yang tidak memiliki kode."
              },
              "destination": {
                "type": "string",
                "nullable": true,
                "description": "Kontak tersamarkan yang menjadi tujuan pengiriman kode."
              },
              "confirmed_at": {
                "type": "string",
                "format": "date-time",
                "nullable": true
              },
              "attempts": {
                "type": "integer",
                "description": "Kode yang dimasukkan, termasuk kode yang benar."
              }
            }
          },
          "timestamp": {
            "type": "object",
            "nullable": true,
            "description": "Stempel waktu RFC 3161 dalam tanda tangan, diterbitkan oleh Didit. `null` hingga ditandatangani, dan selalu `null` untuk tanda tangan Simple.",
            "properties": {
              "time": {
                "type": "string",
                "format": "date-time"
              },
              "qualified": {
                "type": "boolean",
                "description": "Selalu `false` untuk AES."
              },
              "valid": {
                "type": "boolean"
              }
            }
          },
          "documents": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string",
                  "format": "uuid",
                  "description": "Dokumen pada salinan penandatangan ini. Gunakan ini untuk mengunduh berkas yang telah ditandatangani."
                },
                "uuid": {
                  "type": "string",
                  "format": "uuid",
                  "description": "Sama dengan `id`."
                },
                "title": {
                  "type": "string"
                },
                "file_name": {
                  "type": "string"
                },
                "pages": {
                  "type": "integer",
                  "description": "Halaman dokumen yang ditandatangani. Untuk Word, dari PDF yang dikonversi."
                },
                "size_bytes": {
                  "type": "integer"
                },
                "sha256_original": {
                  "type": "string",
                  "description": "SHA-256 dari dokumen persis seperti yang ditampilkan kepada penanda tangan."
                },
                "sha256_signed": {
                  "type": "string",
                  "nullable": true,
                  "description": "SHA-256 dari PDF yang ditandatangani, setelah ditandatangani."
                },
                "status": {
                  "type": "string",
                  "enum": [
                    "signed",
                    "declined",
                    "not_signed",
                    "not_reached"
                  ],
                  "description": "`not_signed`: dibuka tetapi tidak ditandatangani. `not_reached`: tidak pernah dibuka."
                },
                "opened_at": {
                  "type": "string",
                  "format": "date-time",
                  "nullable": true
                },
                "read_at": {
                  "type": "string",
                  "format": "date-time",
                  "nullable": true,
                  "description": "Waktu penandatangan mencapai bagian akhir dokumen tanpa kolom, jika langkah tersebut mewajibkannya."
                },
                "read_to_end": {
                  "type": "boolean"
                },
                "consented_at": {
                  "type": "string",
                  "format": "date-time",
                  "nullable": true,
                  "description": "Waktu penandatangan menyetujui dokumen tanpa kolom, atau menyelesaikan kolom pada dokumen dengan kolom."
                },
                "consent": {
                  "type": "boolean"
                },
                "signed_file": {
                  "type": "string",
                  "nullable": true,
                  "description": "Jalur PDF yang ditandatangani, setelah ditandatangani. Lihat [Unduh dokumen yang ditandatangani](/id/sessions-api/electronic-signature/download-signed-document)."
                },
                "mode": {
                  "type": "string",
                  "enum": [
                    "fields",
                    "read_and_agree"
                  ],
                  "description": "`fields` untuk dokumen dengan kolom, `read_and_agree` untuk dokumen tanpa kolom."
                },
                "source_format": {
                  "type": "string",
                  "enum": [
                    "pdf",
                    "docx"
                  ],
                  "description": "`pdf`, atau `docx` untuk dokumen Word yang dikonversi oleh Didit ke PDF."
                },
                "conversion": {
                  "type": "object",
                  "nullable": true,
                  "description": "`null` untuk PDF. Untuk dokumen Word, file asli dan hasil konversi.",
                  "properties": {
                    "from": {
                      "type": "string",
                      "enum": [
                        "docx"
                      ]
                    },
                    "file_name": {
                      "type": "string",
                      "description": "Nama file Word asli Anda."
                    },
                    "sha256": {
                      "type": "string",
                      "description": "SHA-256 dari file Word asli Anda."
                    },
                    "size_bytes": {
                      "type": "integer",
                      "description": "Ukuran file Word asli Anda."
                    },
                    "converter": {
                      "type": "string",
                      "description": "Versi konverter yang menghasilkan PDF tersebut."
                    }
                  }
                },
                "fields": {
                  "type": "array",
                  "description": "Kolom pada dokumen, beserta nilainya. Kosong untuk dokumen tanpa kolom.",
                  "items": {
                    "$ref": "#/components/schemas/SignatureFieldResult"
                  }
                }
              }
            }
          },
          "adopted_signature": {
            "type": "object",
            "nullable": true,
            "description": "Tanda tangan dan inisial yang ditetapkan penandatangan untuk kolom tanda tangan dan inisial. `null` hingga penandatangan menetapkannya.",
            "properties": {
              "method": {
                "type": "string",
                "enum": [
                  "typed",
                  "drawn"
                ],
                "description": "`typed`: nama terverifikasi dalam gaya tulisan tangan. `drawn`: digambar dengan jari atau mouse."
              },
              "font": {
                "type": "string",
                "nullable": true,
                "description": "Gaya tulisan tangan dari tanda tangan yang diketik. `null` jika digambar."
              },
              "adopted_at": {
                "type": "string",
                "format": "date-time"
              }
            }
          },
          "electronic_signature_consent_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Waktu penandatangan menyetujui, pada layar peninjauan, untuk menandatangani dokumen secara elektronik. Diatur jika ada dokumen yang memiliki kolom."
          },
          "evidence_file": {
            "type": "string",
            "nullable": true,
            "description": "Jalur PDF bukti, setelah ditandatangani. Lihat [Unduh bukti tanda tangan](/id/sessions-api/electronic-signature/download-evidence)."
          },
          "warnings": {
            "type": "array",
            "description": "Peringatan yang dimunculkan untuk penandatangan ini. Lihat [Peringatan Tanda Tangan Elektronik](/id/core-technology/electronic-signature/warnings-electronic-signature).",
            "items": {
              "type": "object",
              "properties": {
                "code": {
                  "type": "string",
                  "enum": [
                    "SIGNATURE_DECLINED",
                    "SIGNATURE_OTP_FAILED",
                    "SIGNATURE_NAME_MISMATCH",
                    "SIGNATURE_IDENTITY_NOT_VERIFIED",
                    "SIGNATURE_DOCUMENT_CHANGED",
                    "SIGNATURE_FIELD_DATA_MISSING"
                  ]
                },
                "node_id": {
                  "type": "string"
                }
              }
            }
          },
          "validation": {
            "type": "object",
            "nullable": true,
            "description": "Pemeriksaan kriptografi terakhir dari dokumen yang ditandatangani. `null` hingga dokumen ditandatangani. Jika Didit tidak dapat mengonfirmasi hasil penandatanganan, nilainya adalah `{\"valid\": null, \"reason\": \"signature_provider_outcome_unknown\", \"checked_at\": ...}` dan `status` tetap `signing`: perlakukan sebagai belum ditandatangani.",
            "properties": {
              "valid": {
                "type": "boolean",
                "nullable": true,
                "description": "`true` jika setiap dokumen valid. `null` jika hasil penandatanganan tidak dapat dikonfirmasi."
              },
              "reason": {
                "type": "string",
                "description": "Ditetapkan saat `valid` bernilai `null`: `signature_provider_outcome_unknown`."
              },
              "checked_at": {
                "type": "string",
                "format": "date-time"
              },
              "documents": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "checked_at": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "valid": {
                      "type": "boolean",
                      "description": "`true` saat tanda tangan dan stempel waktu keduanya valid dan tepercaya."
                    },
                    "integrity": {
                      "type": "boolean",
                      "description": "`true` saat dokumen belum diubah sejak ditandatangani."
                    },
                    "trusted": {
                      "type": "boolean",
                      "description": "`true` saat sertifikat penandatanganan berantai ke akar tepercaya."
                    },
                    "revoked": {
                      "type": "boolean"
                    },
                    "trusted_list": {
                      "type": "object",
                      "description": "Pemeriksaan EU Trusted List. Untuk AES: `{\"status\": \"not_applicable\", \"reason\": \"aes_not_qualified\"}`.",
                      "properties": {
                        "status": {
                          "type": "string"
                        },
                        "reason": {
                          "type": "string"
                        }
                      }
                    },
                    "certificate": {
                      "type": "object",
                      "nullable": true,
                      "description": "Sertifikat yang digunakan untuk menandatangani dokumen. `null` sampai ditandatangani, dan selalu `null` untuk tanda tangan Simple.",
                      "properties": {
                        "issuer": {
                          "type": "string"
                        },
                        "issued_to": {
                          "type": "string"
                        },
                        "serial": {
                          "type": "string",
                          "description": "Nomor seri, heksadesimal."
                        },
                        "valid_from": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "valid_until": {
                          "type": "string",
                          "format": "date-time"
                        }
                      }
                    },
                    "timestamp": {
                      "type": "object",
                      "nullable": true,
                      "description": "Stempel waktu RFC 3161 dalam tanda tangan, diterbitkan oleh Didit. `null` hingga ditandatangani, dan selalu `null` untuk tanda tangan Simple.",
                      "properties": {
                        "time": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "qualified": {
                          "type": "boolean",
                          "description": "Selalu `false` untuk AES."
                        },
                        "valid": {
                          "type": "boolean"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "declined_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "declined_action": {
            "type": "string",
            "enum": [
              "DECLINE",
              "REVIEW",
              "NO_ACTION"
            ]
          },
          "signed_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "expires_at": {
            "type": "string",
            "format": "date-time",
            "description": "Waktu tautan penandatanganan berhenti berfungsi."
          },
          "email_sent_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "email_unavailable_reason": {
            "type": "string",
            "nullable": true
          },
          "ip_address": {
            "type": "string",
            "nullable": true,
            "description": "Alamat IP penandatangan saat mereka meminta kode mereka."
          },
          "place": {
            "type": "string",
            "nullable": true,
            "description": "Tidak dikumpulkan: selalu `null`."
          },
          "place_unavailable_reason": {
            "type": "string",
            "nullable": true,
            "enum": [
              "not_collected"
            ]
          }
        }
      },
      "SignatureFieldValidation": {
        "type": "object",
        "nullable": true,
        "description": "Aturan untuk nilai kolom `text`. Pratinjau konsol, alur penandatanganan, dan API menerapkan aturan yang sama.",
        "properties": {
          "kind": {
            "type": "string",
            "enum": [
              "any",
              "letters",
              "number",
              "email",
              "pattern"
            ],
            "description": "`letters`: huruf dalam aksara apa pun, spasi, tanda hubung, dan apostrof. `number`: digit dengan pemisah desimal opsional. `pattern`: nilai harus cocok dengan `pattern`."
          },
          "min_length": {
            "type": "integer",
            "minimum": 0,
            "maximum": 500,
            "description": "Dari `0` hingga `max_length`."
          },
          "max_length": {
            "type": "integer",
            "minimum": 1,
            "maximum": 500,
            "default": 120
          },
          "pattern": {
            "type": "string",
            "nullable": true,
            "minLength": 1,
            "maxLength": 200,
            "description": "Wajib diisi dengan `kind: \"pattern\"`. Ekspresi reguler yang harus cocok dengan keseluruhan nilai. Lookaround dan backreference tidak didukung."
          },
          "message": {
            "type": "string",
            "nullable": true,
            "maxLength": 120,
            "description": "Ditampilkan kepada penandatangan alih-alih error default."
          }
        }
      },
      "SignatureFieldAnchor": {
        "type": "object",
        "description": "Menempatkan kolom berdasarkan penggalan teks dalam dokumen, bukan berdasarkan posisi. Didit tidak menghapus teks dari PDF, jadi tuliskan teks tersebut dengan warna yang sama seperti latar belakang halaman. Jika teks tidak ditemukan, panggilan mengembalikan `400` dengan `field_anchor_not_found`. Lihat [Menempatkan kolom berdasarkan teks jangkar](/id/sessions-api/create-session#menempatkan-kolom-dengan-teks-penanda).",
        "required": [
          "text"
        ],
        "properties": {
          "text": {
            "type": "string",
            "minLength": 1,
            "maxLength": 64,
            "description": "Teks yang dicari dalam dokumen. Untuk file Word, dalam PDF yang dikonversi."
          },
          "occurrence": {
            "type": "string",
            "enum": [
              "first",
              "all"
            ],
            "default": "first",
            "description": "`all` menempatkan satu kolom per kecocokan; kunci setelah yang pertama mendapatkan `_2`, `_3`, dan seterusnya."
          },
          "offset_x": {
            "type": "number",
            "description": "Ditambahkan ke tepi kiri teks, sebagai fraksi dari lebar halaman."
          },
          "offset_y": {
            "type": "number",
            "description": "Ditambahkan ke tepi atas teks, sebagai fraksi dari tinggi halaman."
          },
          "width": {
            "type": "number",
            "minimum": 0.02,
            "maximum": 1,
            "description": "Lebar kolom, sebagai fraksi dari lebar halaman."
          },
          "height": {
            "type": "number",
            "minimum": 0.012,
            "maximum": 1,
            "description": "Tinggi kolom, sebagai fraksi dari tinggi halaman."
          }
        }
      },
      "SignatureFieldResult": {
        "type": "object",
        "description": "Kolom dari dokumen yang ditandatangani, beserta nilainya pada salinan milik penanda tangan ini. Lihat [Kolom](/id/core-technology/electronic-signature/report-electronic-signature#kolom).",
        "properties": {
          "key": {
            "type": "string",
            "description": "Kunci kolom, seperti yang digunakan dalam `sign.field_values`."
          },
          "type": {
            "type": "string",
            "enum": [
              "signature",
              "initials",
              "full_name",
              "date_signed",
              "text",
              "checkbox",
              "email",
              "data"
            ]
          },
          "role": {
            "type": "string",
            "enum": [
              "verified_person",
              "legal_representative",
              "key_people"
            ]
          },
          "label": {
            "type": "string"
          },
          "page": {
            "type": "integer",
            "description": "Nomor halaman, mulai dari 1. Untuk dokumen Word, halaman dari PDF yang dikonversi."
          },
          "x": {
            "type": "number",
            "description": "Tepi kiri, sebagai fraksi dari lebar halaman."
          },
          "y": {
            "type": "number",
            "description": "Tepi atas, sebagai fraksi dari tinggi halaman."
          },
          "width": {
            "type": "number",
            "description": "Lebar, sebagai fraksi dari lebar halaman."
          },
          "height": {
            "type": "number",
            "description": "Tinggi, sebagai fraksi dari tinggi halaman."
          },
          "required": {
            "type": "boolean"
          },
          "value": {
            "nullable": true,
            "description": "String untuk `text`, `email`, `full_name`, `date_signed`, dan `data`, boolean untuk `checkbox`, dan `true` untuk tanda tangan atau inisial yang dibubuhkan. `null` jika kosong."
          },
          "display_value": {
            "type": "string",
            "nullable": true,
            "description": "Nilai sebagaimana dicantumkan pada halaman: tanggal dalam `date_format` kolom tersebut, `Yes` atau `No` untuk kotak centang, `Signed` untuk tanda tangan atau inisial."
          },
          "value_source": {
            "type": "string",
            "nullable": true,
            "enum": [
              "signer",
              "identity",
              "contact",
              "company",
              "session",
              "metadata",
              "api",
              "signing_time",
              null
            ],
            "description": "Asal nilai: `signer` (diketik, dicentang, atau diterapkan oleh penandatangan), `identity` (ID terverifikasi), `contact` (email atau telepon terverifikasi), `company` (perusahaan terverifikasi), `session` (`vendor_data`), `metadata`, `api` (`sign.field_values`), atau `signing_time` (tanggal ditandatangani)."
          },
          "filled_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "image_url": {
            "type": "string",
            "nullable": true,
            "description": "Hanya tanda tangan dan inisial: jalur gambar yang diterapkan. Lihat [Mengunduh gambar tanda tangan](/id/sessions-api/electronic-signature/download-field-image)."
          },
          "value_unavailable_reason": {
            "type": "string",
            "nullable": true,
            "enum": [
              "source_empty",
              null
            ],
            "description": "`source_empty` saat kolom yang telah diisi sebelumnya tidak memiliki nilai di dalam sesi dan `signature_field_data_missing_action` mengizinkan penandatangan untuk tetap menandatangani."
          }
        }
      },
      "VaspDirectoryWidgetEntry": {
        "type": "object",
        "description": "Apa yang ditampilkan oleh pemilih VASP pengguna akhir: siapa VASP tersebut dan apakah dapat dijangkau.",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "ID entri, untuk GET /v3/travel-rule/vasps/{vasp_id}/."
          },
          "kind": {
            "type": "string",
            "enum": [
              "directory",
              "didit"
            ],
            "description": "directory untuk entri direktori bersama; didit untuk anggota jaringan Didit."
          },
          "name": {
            "type": "string"
          },
          "lei": {
            "type": "string"
          },
          "jurisdiction": {
            "type": "string",
            "description": "Kode negara ISO 3166, sesuai yang diberikan oleh sumber."
          },
          "domains": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Domain web VASP. Selalu kosong untuk anggota jaringan Didit."
          },
          "reachable": {
            "type": "boolean",
            "description": "Menentukan apakah aplikasi Anda memiliki rute yang tersedia ke VASP ini, atau ke salah satu entitasnya untuk suatu merek. Selalu true untuk anggota jaringan Didit."
          }
        }
      },
      "TravelRuleDataSharingFields": {
        "type": "object",
        "description": "Kolom yang dikirimkan Didit ke VASP pihak lawan tentang pengguna Anda sendiri, per jenis entitas. `name` dan `wallet_address` selalu dikirim, apa pun isi daftarnya. Jenis entitas yang tidak pernah Anda pilih membagikan setiap kolom. Daftar kosong juga merupakan pilihan: daftar ini hanya membagikan nama dan dompet.",
        "properties": {
          "individual": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "name",
                "wallet_address",
                "address",
                "national_id",
                "customer_identification",
                "date_of_birth",
                "place_of_birth"
              ]
            },
            "description": "Kolom yang dibagikan tentang individu."
          },
          "company": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "name",
                "wallet_address",
                "address",
                "national_id",
                "customer_identification"
              ]
            },
            "description": "Kolom yang dibagikan tentang badan hukum."
          }
        }
      },
      "TravelRuleMatchingRules": {
        "type": "object",
        "description": "Seberapa ketat setiap kolom data pihak lawan dibandingkan dengan data yang Anda miliki, per tipe entitas. Kolom yang Anda lewatkan akan tetap menggunakan nilai default-nya. `NONE` melewati perbandingan, `STRICT` memerlukan kata-kata yang persis sama, `CONTAINS` menerima satu nilai yang semua katanya muncul di nilai lainnya, `DEFAULT` adalah pencocokan subset standar, dan `FUZZY` menerima ejaan yang mirip (dan, untuk tanggal lahir, hari dan bulan yang tertukar).",
        "properties": {
          "individual": {
            "type": "object",
            "description": "Aturan untuk orang pribadi.",
            "properties": {
              "name": {
                "type": "string",
                "enum": [
                  "NONE",
                  "STRICT",
                  "CONTAINS",
                  "DEFAULT",
                  "FUZZY"
                ],
                "description": "Default: mengikuti `name_matching_strictness`."
              },
              "date_of_birth": {
                "type": "string",
                "enum": [
                  "NONE",
                  "STRICT",
                  "CONTAINS",
                  "DEFAULT",
                  "FUZZY"
                ],
                "description": "Default `NONE`."
              },
              "address": {
                "type": "string",
                "enum": [
                  "NONE",
                  "STRICT",
                  "CONTAINS",
                  "DEFAULT",
                  "FUZZY"
                ],
                "description": "Default `NONE`."
              },
              "account": {
                "type": "string",
                "enum": [
                  "NONE",
                  "STRICT",
                  "CONTAINS",
                  "DEFAULT",
                  "FUZZY"
                ],
                "description": "Dompet yang digunakan untuk merutekan pertukaran. Default `STRICT`."
              }
            }
          },
          "company": {
            "type": "object",
            "description": "Aturan untuk badan hukum.",
            "properties": {
              "name": {
                "type": "string",
                "enum": [
                  "NONE",
                  "STRICT",
                  "CONTAINS",
                  "DEFAULT",
                  "FUZZY"
                ],
                "description": "Default: mengikuti `name_matching_strictness`."
              },
              "address": {
                "type": "string",
                "enum": [
                  "NONE",
                  "STRICT",
                  "CONTAINS",
                  "DEFAULT",
                  "FUZZY"
                ],
                "description": "Default `NONE`."
              },
              "account": {
                "type": "string",
                "enum": [
                  "NONE",
                  "STRICT",
                  "CONTAINS",
                  "DEFAULT",
                  "FUZZY"
                ],
                "description": "Dompet yang digunakan untuk merutekan pertukaran. Default `STRICT`."
              }
            }
          }
        }
      },
      "TravelRuleDataMatch": {
        "type": "object",
        "nullable": true,
        "description": "Perbandingan kolom demi kolom antara data pihak transfer dan apa yang diketahui pihak lain tentang pemegang dompet. Ini menyebutkan kolom dan hasil, tidak pernah nilai, sehingga tetap dapat dibaca sementara data pihak lawan disamarkan. Bernilai null sampai perbandingan dijalankan.",
        "properties": {
          "matched": {
            "type": "boolean",
            "description": "True saat tidak ada kolom yang dibandingkan yang berbeda."
          },
          "mismatched_fields": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "name",
                "date_of_birth",
                "address",
                "account"
              ]
            },
            "description": "Kolom yang berbeda."
          },
          "fields": {
            "type": "object",
            "description": "Satu entri per kolom yang dibandingkan untuk tipe entitas pihak tersebut (`name`, `date_of_birth`, `address`, `account`; perusahaan tidak memiliki `date_of_birth`).",
            "additionalProperties": {
              "type": "object",
              "properties": {
                "result": {
                  "type": "string",
                  "enum": [
                    "matched",
                    "mismatched",
                    "not_compared"
                  ],
                  "description": "`not_compared` saat aturan bernilai `NONE` atau salah satu pihak tidak memiliki nilai untuk kolom tersebut."
                },
                "strictness": {
                  "type": "string",
                  "enum": [
                    "NONE",
                    "STRICT",
                    "CONTAINS",
                    "DEFAULT",
                    "FUZZY"
                  ]
                }
              }
            }
          }
        }
      },
      "TravelRuleDataUnmasked": {
        "type": "object",
        "nullable": true,
        "description": "Catatan audit saat data pihak lawan dibuka penyamarannya. Bernilai null selama data masih disamarkan, dan untuk transfer keluar.",
        "properties": {
          "at": {
            "type": "string",
            "format": "date-time"
          },
          "reason": {
            "type": "string",
            "enum": [
              "ownership_confirmed",
              "wallet_proof",
              "address_book_match",
              "own_verified_wallet",
              "inquiry_approved",
              "known_payment_method",
              "travel_address"
            ],
            "description": "Hal yang mengonfirmasi kepemilikan: ownership_confirmed (konfirmasi Anda melalui konsol atau API), wallet_proof (bukti dompet di widget, atau transfer masuk INTERNAL, ditetapkan saat dibuat), address_book_match (dompet di buku alamat yang terverifikasi), own_verified_wallet (dompet terverifikasi milik pengguna Anda sendiri), inquiry_approved (persetujuan Anda atas permintaan masuk TRP atau pesan GTR atau Sygna), known_payment_method (dompet yang sudah digunakan pengguna Anda untuk membayar) atau travel_address (Travel Address per dompet mencantumkan dompet tersebut)."
          },
          "actor": {
            "type": "string",
            "description": "Pihak yang mengonfirmasinya: email pengguna konsol atau label kunci API. Kosong untuk keputusan otomatis."
          }
        }
      },
      "TravelRuleMessageAttachment": {
        "type": "object",
        "nullable": true,
        "description": "Dokumen yang dilampirkan ke pesan, disimpan seperti dokumen transaksi lainnya.",
        "properties": {
          "uuid": {
            "type": "string",
            "format": "uuid"
          },
          "label": {
            "type": "string",
            "nullable": true
          },
          "note": {
            "type": "string",
            "nullable": true
          },
          "uploaded_by": {
            "type": "string",
            "nullable": true,
            "description": "Pihak yang melampirkannya. Di portal pengambilan, file yang Anda kirim menampilkan nama VASP Anda, tidak pernah menampilkan orang atau kunci API di baliknya."
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "files": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "uuid": {
                  "type": "string",
                  "format": "uuid"
                },
                "file_url": {
                  "type": "string",
                  "nullable": true,
                  "description": "URL unduhan dengan batas waktu."
                },
                "original_filename": {
                  "type": "string"
                },
                "file_size": {
                  "type": "integer"
                }
              }
            }
          }
        }
      },
      "TravelRuleMessage": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "kind": {
            "type": "string",
            "enum": [
              "MESSAGE",
              "DOCUMENT_REQUEST"
            ]
          },
          "direction": {
            "type": "string",
            "enum": [
              "INBOUND",
              "OUTBOUND"
            ],
            "description": "`OUTBOUND` adalah apa yang dikirim oleh pihak pembaca sendiri. Di portal penjemputan, arahnya adalah dari pihak lawan."
          },
          "author": {
            "type": "string",
            "description": "Pihak yang menulisnya dari pihaknya sendiri: email pengguna konsol atau label kunci API, atau nama VASP lainnya."
          },
          "body": {
            "type": "string"
          },
          "requested_documents": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Apa yang diminta oleh DOCUMENT_REQUEST, dalam kata-kata pemohon."
          },
          "reply_to": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "fulfilled_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Ditetapkan pada DOCUMENT_REQUEST setelah balasan untuknya membawa dokumen."
          },
          "attachment": {
            "$ref": "#/components/schemas/TravelRuleMessageAttachment"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "TravelRuleMessageCreateRequest": {
        "type": "object",
        "description": "Kirim sebagai JSON, atau sebagai multipart/form-data dengan lampiran di `files`.",
        "properties": {
          "kind": {
            "type": "string",
            "enum": [
              "MESSAGE",
              "DOCUMENT_REQUEST"
            ],
            "default": "MESSAGE"
          },
          "body": {
            "type": "string",
            "maxLength": 5000,
            "description": "Wajib untuk MESSAGE kecuali jika file dilampirkan."
          },
          "requested_documents": {
            "type": "array",
            "items": {
              "type": "string",
              "maxLength": 255
            },
            "maxItems": 10,
            "description": "Wajib (setidaknya satu) untuk DOCUMENT_REQUEST, dan hanya diizinkan di sana."
          },
          "reply_to": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "Pesan dari transfer yang sama. Balasan yang menyertakan dokumen memenuhi permintaan dokumen yang dijawabnya."
          },
          "files": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "binary"
            },
            "maxItems": 5,
            "description": "Hanya multipart. Hingga 5 file masing-masing berukuran 10 MB."
          }
        }
      },
      "SessionDeletionJob": {
        "type": "object",
        "description": "Penghapusan sesi massal yang berjalan di latar belakang: progres dan jumlah per hasil, tidak pernah menampilkan sesi mana saja yang dihapusnya.",
        "properties": {
          "job_id": {
            "type": "string",
            "format": "uuid",
            "description": "Lakukan polling `GET /v3/sessions/delete/{job_id}/` dengan id ini."
          },
          "status": {
            "type": "string",
            "enum": [
              "PENDING",
              "PROCESSING",
              "COMPLETED",
              "FAILED"
            ],
            "description": "`PENDING`: diterima, belum dimulai. `PROCESSING`: sedang menghapus; `processed` dan `outcomes` sedang diperbarui. `COMPLETED`: setiap sesi yang dipilih telah ditangani. `FAILED`: pekerjaan berhenti lebih awal; lihat `error`."
          },
          "total": {
            "type": "integer",
            "description": "Sesi yang dipilih saat penghapusan diminta."
          },
          "processed": {
            "type": "integer",
            "description": "Sesi yang telah selesai diproses oleh pekerjaan sejauh ini."
          },
          "outcomes": {
            "type": "object",
            "description": "Berapa banyak sesi yang berakhir di setiap hasil. Setiap kunci selalu ada.",
            "properties": {
              "deleted": {
                "type": "integer",
                "description": "Sesi yang dihapus bersama dengan embedding wajahnya."
              },
              "none": {
                "type": "integer",
                "description": "Sesi yang dihapus yang tidak memiliki embedding wajah."
              },
              "retained_with_user": {
                "type": "integer",
                "description": "Sesi yang dihapus sementara satu templat biometrik bebas gambar dipertahankan untuk Pengguna mereka, sesuai permintaan atau kebijakan aplikasi."
              },
              "ineligible_no_vendor_user": {
                "type": "integer",
                "description": "Sesi yang dihapus, bersama dengan embedding wajahnya, karena retensi diminta tetapi mereka tidak memiliki Pengguna yang ditautkan."
              },
              "failed_retryable": {
                "type": "integer",
                "description": "Sesi yang dilaporkan belum dihapus. Pekerjaan mencoba lagi grup yang tidak dapat dihapusnya sendiri alih-alih menghitungnya di sini."
              },
              "already_deleted": {
                "type": "integer",
                "description": "Sesi terpilih yang sudah dihapus, misalnya oleh permintaan lain, ketika tugas mencapainya."
              }
            }
          },
          "deleted_child_verifications": {
            "type": "integer",
            "description": "Verifikasi yang dibuat oleh verifikasi bisnis yang dihapus, yang dihapus bersamanya. Selalu `0` untuk pekerjaan yang dimulai oleh `POST /v3/sessions/delete/`, yang hanya menghapus sesi KYC."
          },
          "error": {
            "type": "string",
            "nullable": true,
            "description": "`null` kecuali jika `status` bernilai `FAILED`; kemudian alasan mengapa penghapusan berhenti. Sesi yang belum tercapai oleh tugas masih tetap ada: ulangi permintaan untuk menghapusnya."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "Waktu ketika penghapusan diminta."
          },
          "completed_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Waktu pekerjaan selesai; `null` selama pekerjaan berjalan."
          }
        }
      },
      "EntityStatusUpdateRequest": {
        "type": "object",
        "required": [
          "status"
        ],
        "properties": {
          "status": {
            "type": "string",
            "enum": [
              "ACTIVE",
              "FLAGGED",
              "BLOCKED"
            ],
            "description": "Status siklus hidup baru. `BLOCKED` juga menambahkan `vendor_data` ke daftar blokir sistem."
          }
        }
      },
      "AMLMonitoringToggleResult": {
        "oneOf": [
          {
            "type": "object",
            "required": [
              "users_total",
              "already_enabled",
              "with_existing_aml",
              "needing_screening",
              "skipped_no_identity_data",
              "skipped_blocked",
              "estimated_screening_cost_usd",
              "estimated_annual_monitoring_cost_usd",
              "balance_sufficient",
              "unmatched"
            ],
            "description": "Pratinjau biaya. Dikembalikan secara langsung saat estimate_only bernilai true (tidak ada yang ditulis).",
            "properties": {
              "users_total": {
                "type": "integer",
                "description": "Profil yang cocok dengan pilihan."
              },
              "already_enabled": {
                "type": "integer",
                "description": "Profil yang sudah dipantau (tidak ada tindakan saat mengaktifkan; ini adalah profil yang dimatikan saat dinonaktifkan)."
              },
              "with_existing_aml": {
                "type": "integer",
                "description": "Profil yang skrining AML-nya yang sudah ada akan dialihkan ke dipantau (tanpa skrining baru)."
              },
              "needing_screening": {
                "type": "integer",
                "description": "Profil tanpa skrining AML apa pun yang akan diskrining terlebih dahulu (ditagih sebagai skrining AML reguler)."
              },
              "skipped_no_identity_data": {
                "type": "integer",
                "description": "Profil yang tidak dapat diskrining karena data identitas tidak tersedia."
              },
              "skipped_blocked": {
                "type": "integer",
                "description": "Pengguna terblokir yang akan dilewati (selalu 0 untuk bisnis)."
              },
              "estimated_screening_cost_usd": {
                "type": "number",
                "example": 0.2,
                "description": "Biaya sekali bayar untuk skrining baru."
              },
              "estimated_annual_monitoring_cost_usd": {
                "type": "number",
                "example": 0.07,
                "description": "Biaya pemantauan tahunan dari profil yang akan dipantau."
              },
              "balance_sufficient": {
                "type": "boolean",
                "description": "Apakah saldo organisasi mencukupi untuk skrining ditambah tahun pertama pemantauan."
              },
              "unmatched": {
                "type": "array",
                "items": {
                  "type": "string"
                },
                "description": "Pengenal permintaan yang tidak cocok dengan profil apa pun di aplikasi ini, persis seperti yang dikirim."
              }
            }
          },
          {
            "type": "object",
            "required": [
              "job_id",
              "status",
              "is_enabled",
              "target_type",
              "total",
              "processed",
              "outcomes",
              "results",
              "error",
              "created_at",
              "completed_at",
              "estimate",
              "unmatched"
            ],
            "properties": {
              "job_id": {
                "type": "string",
                "format": "uuid"
              },
              "status": {
                "type": "string",
                "enum": [
                  "PENDING",
                  "PROCESSING",
                  "COMPLETED",
                  "FAILED"
                ]
              },
              "is_enabled": {
                "type": "boolean",
                "description": "true saat pekerjaan mengaktifkan pemantauan, false saat menonaktifkannya."
              },
              "target_type": {
                "type": "string",
                "enum": [
                  "user",
                  "business"
                ],
                "description": "Famili profil mana yang diaktif-nonaktifkan oleh tugas ini."
              },
              "total": {
                "type": "integer",
                "description": "Profil yang diproses oleh tugas."
              },
              "processed": {
                "type": "integer",
                "description": "Profil yang diproses sejauh ini."
              },
              "outcomes": {
                "type": "object",
                "description": "Penghitung hasil per rekaman. Setiap profil yang dipilih dipetakan ke tepat satu penghitung; tidak ada yang dilewati secara diam-diam.",
                "properties": {
                  "enabled": {
                    "type": "integer",
                    "description": "Pemantauan diaktifkan pada skrining AML yang ada."
                  },
                  "screened_and_enabled": {
                    "type": "integer",
                    "description": "Skrining AML baru telah dibuat (ditagihkan) dan pemantauan diaktifkan untuk skrining tersebut."
                  },
                  "already_enabled": {
                    "type": "integer",
                    "description": "Pemantauan sudah aktif sebelumnya; tidak ada yang berubah dan tidak ada yang ditagihkan."
                  },
                  "disabled": {
                    "type": "integer",
                    "description": "Pemantauan dinonaktifkan di semua skrining AML profil."
                  },
                  "skipped_no_identity_data": {
                    "type": "integer",
                    "description": "Dilewati: profil tidak memiliki nama lengkap, tanggal lahir, dan negara (pengguna) atau nama (bisnis) yang diperlukan untuk diskrining."
                  },
                  "skipped_blocked": {
                    "type": "integer",
                    "description": "Dilewati: pengguna diblokir."
                  },
                  "skipped_sandbox": {
                    "type": "integer",
                    "description": "Dilewati: aplikasi sandbox, tidak ada skrining yang dibuat."
                  },
                  "failed_provider": {
                    "type": "integer",
                    "description": "Skrining tidak dapat diselesaikan; coba lagi nanti."
                  },
                  "failed_insufficient_balance": {
                    "type": "integer",
                    "description": "Saldo habis saat pekerjaan sedang berjalan."
                  }
                }
              },
              "results": {
                "type": "array",
                "description": "Satu entri per profil yang diproses, sesuai urutan pemrosesan. Bertambah saat tugas berjalan; lengkap setelah statusnya COMPLETED. Dicatat untuk tugas yang dimulai melalui API.",
                "items": {
                  "type": "object",
                  "properties": {
                    "didit_internal_id": {
                      "type": "string",
                      "format": "uuid",
                      "description": "ID internal Didit untuk profil tersebut."
                    },
                    "vendor_data": {
                      "type": "string",
                      "nullable": true,
                      "description": "Pengenal Anda sendiri untuk profil tersebut."
                    },
                    "outcome": {
                      "type": "string",
                      "enum": [
                        "enabled",
                        "screened_and_enabled",
                        "already_enabled",
                        "disabled",
                        "skipped_no_identity_data",
                        "skipped_blocked",
                        "skipped_sandbox",
                        "failed_provider",
                        "failed_insufficient_balance"
                      ]
                    }
                  }
                }
              },
              "error": {
                "type": "string",
                "nullable": true,
                "description": "Pesan kegagalan umum saat status FAILED; penyebab terperinci disimpan di sisi platform."
              },
              "created_at": {
                "type": "string",
                "format": "date-time"
              },
              "completed_at": {
                "type": "string",
                "format": "date-time",
                "nullable": true
              },
              "estimate": {
                "type": "object",
                "description": "Pratinjau biaya. Dikembalikan secara langsung saat estimate_only bernilai true (tidak ada yang ditulis).",
                "properties": {
                  "users_total": {
                    "type": "integer",
                    "description": "Profil yang cocok dengan pilihan."
                  },
                  "already_enabled": {
                    "type": "integer",
                    "description": "Profil yang sudah dipantau (tidak ada tindakan saat mengaktifkan; ini adalah profil yang dimatikan saat dinonaktifkan)."
                  },
                  "with_existing_aml": {
                    "type": "integer",
                    "description": "Profil yang skrining AML-nya yang sudah ada akan dialihkan ke dipantau (tanpa skrining baru)."
                  },
                  "needing_screening": {
                    "type": "integer",
                    "description": "Profil tanpa skrining AML apa pun yang akan diskrining terlebih dahulu (ditagih sebagai skrining AML reguler)."
                  },
                  "skipped_no_identity_data": {
                    "type": "integer",
                    "description": "Profil yang tidak dapat diskrining karena data identitas tidak tersedia."
                  },
                  "skipped_blocked": {
                    "type": "integer",
                    "description": "Pengguna terblokir yang akan dilewati (selalu 0 untuk bisnis)."
                  },
                  "estimated_screening_cost_usd": {
                    "type": "number",
                    "example": 0.2,
                    "description": "Biaya sekali bayar untuk skrining baru."
                  },
                  "estimated_annual_monitoring_cost_usd": {
                    "type": "number",
                    "example": 0.07,
                    "description": "Biaya pemantauan tahunan dari profil yang akan dipantau."
                  },
                  "balance_sufficient": {
                    "type": "boolean",
                    "description": "Apakah saldo organisasi mencukupi untuk skrining ditambah tahun pertama pemantauan."
                  }
                }
              },
              "unmatched": {
                "type": "array",
                "items": {
                  "type": "string"
                },
                "description": "Pengenal permintaan yang tidak cocok dengan profil apa pun di aplikasi ini, persis seperti yang dikirim. Pengenal ini bukan bagian dari pekerjaan."
              }
            }
          }
        ]
      },
      "AMLMonitoringJob": {
        "type": "object",
        "properties": {
          "job_id": {
            "type": "string",
            "format": "uuid"
          },
          "status": {
            "type": "string",
            "enum": [
              "PENDING",
              "PROCESSING",
              "COMPLETED",
              "FAILED"
            ]
          },
          "is_enabled": {
            "type": "boolean",
            "description": "true saat pekerjaan mengaktifkan pemantauan, false saat menonaktifkannya."
          },
          "target_type": {
            "type": "string",
            "enum": [
              "user",
              "business"
            ],
            "description": "Famili profil mana yang diaktif-nonaktifkan oleh tugas ini."
          },
          "total": {
            "type": "integer",
            "description": "Profil yang diproses oleh tugas."
          },
          "processed": {
            "type": "integer",
            "description": "Profil yang diproses sejauh ini."
          },
          "outcomes": {
            "type": "object",
            "description": "Penghitung hasil per rekaman. Setiap profil yang dipilih dipetakan ke tepat satu penghitung; tidak ada yang dilewati secara diam-diam.",
            "properties": {
              "enabled": {
                "type": "integer",
                "description": "Pemantauan diaktifkan pada skrining AML yang ada."
              },
              "screened_and_enabled": {
                "type": "integer",
                "description": "Skrining AML baru telah dibuat (ditagihkan) dan pemantauan diaktifkan untuk skrining tersebut."
              },
              "already_enabled": {
                "type": "integer",
                "description": "Pemantauan sudah aktif sebelumnya; tidak ada yang berubah dan tidak ada yang ditagihkan."
              },
              "disabled": {
                "type": "integer",
                "description": "Pemantauan dinonaktifkan di semua skrining AML profil."
              },
              "skipped_no_identity_data": {
                "type": "integer",
                "description": "Dilewati: profil tidak memiliki nama lengkap, tanggal lahir, dan negara (pengguna) atau nama (bisnis) yang diperlukan untuk diskrining."
              },
              "skipped_blocked": {
                "type": "integer",
                "description": "Dilewati: pengguna diblokir."
              },
              "skipped_sandbox": {
                "type": "integer",
                "description": "Dilewati: aplikasi sandbox, tidak ada skrining yang dibuat."
              },
              "failed_provider": {
                "type": "integer",
                "description": "Skrining tidak dapat diselesaikan; coba lagi nanti."
              },
              "failed_insufficient_balance": {
                "type": "integer",
                "description": "Saldo habis saat pekerjaan sedang berjalan."
              }
            }
          },
          "results": {
            "type": "array",
            "description": "Satu entri per profil yang diproses, sesuai urutan pemrosesan. Bertambah saat tugas berjalan; lengkap setelah statusnya COMPLETED. Dicatat untuk tugas yang dimulai melalui API.",
            "items": {
              "type": "object",
              "properties": {
                "didit_internal_id": {
                  "type": "string",
                  "format": "uuid",
                  "description": "ID internal Didit untuk profil tersebut."
                },
                "vendor_data": {
                  "type": "string",
                  "nullable": true,
                  "description": "Pengenal Anda sendiri untuk profil tersebut."
                },
                "outcome": {
                  "type": "string",
                  "enum": [
                    "enabled",
                    "screened_and_enabled",
                    "already_enabled",
                    "disabled",
                    "skipped_no_identity_data",
                    "skipped_blocked",
                    "skipped_sandbox",
                    "failed_provider",
                    "failed_insufficient_balance"
                  ]
                }
              }
            }
          },
          "error": {
            "type": "string",
            "nullable": true,
            "description": "Pesan kegagalan umum saat status FAILED; penyebab terperinci disimpan di sisi platform."
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "completed_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "estimate": {
            "type": "object",
            "description": "Pratinjau biaya. Dikembalikan secara langsung saat estimate_only bernilai true (tidak ada yang ditulis).",
            "properties": {
              "users_total": {
                "type": "integer",
                "description": "Profil yang cocok dengan pilihan."
              },
              "already_enabled": {
                "type": "integer",
                "description": "Profil yang sudah dipantau (tidak ada tindakan saat mengaktifkan; ini adalah profil yang dimatikan saat dinonaktifkan)."
              },
              "with_existing_aml": {
                "type": "integer",
                "description": "Profil yang skrining AML-nya yang sudah ada akan dialihkan ke dipantau (tanpa skrining baru)."
              },
              "needing_screening": {
                "type": "integer",
                "description": "Profil tanpa skrining AML apa pun yang akan diskrining terlebih dahulu (ditagih sebagai skrining AML reguler)."
              },
              "skipped_no_identity_data": {
                "type": "integer",
                "description": "Profil yang tidak dapat diskrining karena data identitas tidak tersedia."
              },
              "skipped_blocked": {
                "type": "integer",
                "description": "Pengguna terblokir yang akan dilewati (selalu 0 untuk bisnis)."
              },
              "estimated_screening_cost_usd": {
                "type": "number",
                "example": 0.2,
                "description": "Biaya sekali bayar untuk skrining baru."
              },
              "estimated_annual_monitoring_cost_usd": {
                "type": "number",
                "example": 0.07,
                "description": "Biaya pemantauan tahunan dari profil yang akan dipantau."
              },
              "balance_sufficient": {
                "type": "boolean",
                "description": "Apakah saldo organisasi mencukupi untuk skrining ditambah tahun pertama pemantauan."
              }
            }
          },
          "unmatched": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Pengenal permintaan yang tidak cocok dengan profil apa pun di aplikasi ini, persis seperti yang dikirim. Pengenal ini bukan bagian dari pekerjaan."
          }
        }
      },
      "OngoingMonitoringToggleRequest": {
        "type": "object",
        "required": [
          "is_enabled"
        ],
        "properties": {
          "is_enabled": {
            "type": "boolean",
            "description": "true untuk mengaktifkan pemantauan, false untuk menonaktifkannya."
          },
          "estimate_only": {
            "type": "boolean",
            "default": false,
            "description": "Jika true, mengembalikan estimasi biaya dan tidak melakukan penulisan data."
          },
          "update_all": {
            "type": "boolean",
            "default": false,
            "description": "Terapkan ke setiap entitas aplikasi (dibatasi oleh parameter filter_* jika ada)."
          },
          "filter_search": {
            "type": "string"
          },
          "filter_status": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "filter_country": {
            "type": "string"
          },
          "filter_date_from": {
            "type": "string",
            "format": "date"
          },
          "filter_date_to": {
            "type": "string",
            "format": "date"
          },
          "didit_internal_id_list": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Entitas yang statusnya akan diubah. Wajib diisi kecuali jika update_all bernilai true."
          }
        }
      },
      "OngoingMonitoringJob": {
        "type": "object",
        "properties": {
          "job_id": {
            "type": "string",
            "format": "uuid"
          },
          "status": {
            "type": "string",
            "enum": [
              "PENDING",
              "PROCESSING",
              "COMPLETED",
              "FAILED"
            ]
          },
          "is_enabled": {
            "type": "boolean"
          },
          "total": {
            "type": "integer"
          },
          "processed": {
            "type": "integer"
          },
          "outcomes": {
            "type": "object",
            "description": "Penghitung hasil per entitas. Tidak ada yang dilewati secara diam-diam: setiap entitas yang diminta diselesaikan ke tepat satu penghitung.",
            "properties": {
              "enabled": {
                "type": "integer",
                "description": "Pemantauan diaktifkan pada skrining AML yang ada."
              },
              "screened_and_enabled": {
                "type": "integer",
                "description": "Skrining AML baru telah dibuat (ditagihkan) dan pemantauan diaktifkan."
              },
              "already_enabled": {
                "type": "integer",
                "description": "Pemantauan sudah aktif sebelumnya (baris duplikat lama dikonsolidasikan)."
              },
              "disabled": {
                "type": "integer",
                "description": "Pemantauan dinonaktifkan pada setiap baris AML entitas."
              },
              "skipped_no_identity_data": {
                "type": "integer",
                "description": "Dilewati: nama lengkap + tanggal lahir + negara tidak tersedia untuk diskrining."
              },
              "skipped_blocked": {
                "type": "integer",
                "description": "Dilewati: pengguna diblokir."
              },
              "skipped_sandbox": {
                "type": "integer",
                "description": "Dilewati: aplikasi sandbox."
              },
              "failed_provider": {
                "type": "integer",
                "description": "Panggilan penyedia skrining gagal."
              },
              "failed_insufficient_balance": {
                "type": "integer",
                "description": "Saldo habis di tengah pekerjaan."
              }
            }
          },
          "error": {
            "type": "string",
            "nullable": true
          },
          "estimate": {
            "type": "object",
            "description": "Pratinjau biaya. Dikembalikan secara langsung saat estimate_only bernilai true (tidak ada operasi tulis yang dilakukan).",
            "properties": {
              "users_total": {
                "type": "integer",
                "description": "Entitas dalam pilihan."
              },
              "already_enabled": {
                "type": "integer"
              },
              "with_existing_aml": {
                "type": "integer",
                "description": "Entitas yang Skrining AML-nya sudah ada akan diaktifkan pemantauannya."
              },
              "needing_screening": {
                "type": "integer",
                "description": "Entitas tanpa skrining AML apa pun yang akan diskrining terlebih dahulu (ditagih)."
              },
              "skipped_no_identity_data": {
                "type": "integer"
              },
              "skipped_blocked": {
                "type": "integer"
              },
              "estimated_screening_cost_usd": {
                "type": "number",
                "example": 0.2
              },
              "estimated_annual_monitoring_cost_usd": {
                "type": "number",
                "example": 0.07
              },
              "balance_sufficient": {
                "type": "boolean"
              }
            }
          }
        }
      },
      "OngoingMonitoringToggleResult": {
        "oneOf": [
          {
            "type": "object",
            "description": "Pratinjau biaya. Dikembalikan secara langsung saat estimate_only bernilai true (tidak ada operasi tulis yang dilakukan).",
            "properties": {
              "users_total": {
                "type": "integer",
                "description": "Entitas dalam pilihan."
              },
              "already_enabled": {
                "type": "integer"
              },
              "with_existing_aml": {
                "type": "integer",
                "description": "Entitas yang Skrining AML-nya sudah ada akan diaktifkan pemantauannya."
              },
              "needing_screening": {
                "type": "integer",
                "description": "Entitas tanpa skrining AML apa pun yang akan diskrining terlebih dahulu (ditagih)."
              },
              "skipped_no_identity_data": {
                "type": "integer"
              },
              "skipped_blocked": {
                "type": "integer"
              },
              "estimated_screening_cost_usd": {
                "type": "number",
                "example": 0.2
              },
              "estimated_annual_monitoring_cost_usd": {
                "type": "number",
                "example": 0.07
              },
              "balance_sufficient": {
                "type": "boolean"
              }
            }
          },
          {
            "$ref": "#/components/schemas/OngoingMonitoringJob"
          }
        ]
      },
      "CaseBlueprintPresetInstallResult": {
        "type": "object",
        "properties": {
          "created": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        }
      },
      "CaseBulkUpdateResult": {
        "type": "object",
        "properties": {
          "updated": {
            "type": "integer"
          },
          "failures": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "case_uuid": {
                  "type": "string",
                  "format": "uuid"
                },
                "detail": {
                  "type": "string"
                }
              }
            }
          }
        }
      },
      "RegulatoryReportList": {
        "type": "object",
        "properties": {
          "count": {
            "type": "integer",
            "description": "Jumlah baris yang cocok, dibatasi pada 100 demi performa."
          },
          "next": {
            "type": "string",
            "nullable": true
          },
          "previous": {
            "type": "string",
            "nullable": true
          },
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/RegulatoryReportDetail"
            }
          }
        }
      },
      "EntityNetworkMembershipList": {
        "type": "object",
        "properties": {
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/EntityNetworkMembership"
            }
          }
        }
      },
      "SessionDecision": {
        "type": "object",
        "properties": {
          "session_id": {
            "type": "string",
            "format": "uuid",
            "description": "Pengidentifikasi unik sesi."
          },
          "session_kind": {
            "type": "string",
            "enum": [
              "user",
              "business"
            ],
            "description": "Diskriminator yang menunjukkan apakah ini sesi Verifikasi Pengguna (KYC) atau Verifikasi Bisnis (KYB). Jika `user`, array fitur KYC (`id_verifications`, `nfc_verifications`, `liveness_checks`, `face_matches`, `poa_verifications`, `document_ai_documents`, `database_validations`, ...) berlaku dan array bisnis tidak ada. Jika `business`, payload memuat `registry_checks`, `document_verifications`, `key_people_checks` ditambah array bersama (`aml_screenings`, `phone_verifications`, `email_verifications`, `ip_analyses`, `questionnaire_responses`). **Ditiadakan ketika `include=events` diteruskan** — bentuk event hanya ada untuk sesi pengguna, sehingga diskriminator dihapus dari varian tersebut."
          },
          "shared_from_session": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "Untuk sesi yang dikloning dengan `POST /v3/session/import-shared/`: `session_id` dari sesi asli di aplikasi sumber. `null` untuk setiap sesi lainnya. Dihilangkan jika `include=events` diteruskan."
          },
          "shared_from_session_number": {
            "type": "integer",
            "nullable": true,
            "description": "`session_number` dari sesi sumber saat sesi ini diimpor dari aplikasi lain milik organisasi Anda. `null` jika tidak."
          },
          "session_number": {
            "type": "integer",
            "description": "Nomor sesi.",
            "nullable": true
          },
          "session_url": {
            "type": "string",
            "format": "uri",
            "description": "URL sesi.",
            "nullable": true
          },
          "status": {
            "type": "string",
            "enum": [
              "Not Started",
              "In Progress",
              "Awaiting User",
              "In Review",
              "Approved",
              "Declined",
              "Resubmitted",
              "Expired",
              "Kyc Expired",
              "Abandoned"
            ],
            "description": "Status siklus hidup keseluruhan dari sesi — hasil alur kerja agregat. Nilai akhir adalah `Approved`, `Declined`, `In Review`, `Expired`, `Kyc Expired`, dan `Abandoned`; `Not Started`, `In Progress`, `Awaiting User`, dan `Resubmitted` menunjukkan bahwa sesi masih bergerak melalui alur kerja."
          },
          "status_override": {
            "type": "object",
            "nullable": true,
            "description": "Hadir ketika peninjau menetapkan `status` secara manual. Bernilai `null` jika statusnya otomatis. Gunakan ini untuk membedakan persetujuan manual dari yang otomatis.",
            "properties": {
              "overridden_at": {
                "type": "string",
                "format": "date-time",
                "nullable": true
              },
              "automatic_status": {
                "type": "string",
                "nullable": true,
                "description": "Status yang disimpulkan dari pemeriksaan platform itu sendiri."
              }
            }
          },
          "decision_trace": {
            "type": "object",
            "description": "Bagaimana status tersebut tercapai: siapa yang mengaturnya dan peringatan mana yang memicunya.",
            "properties": {
              "status": {
                "type": "string",
                "description": "Status sesi."
              },
              "decided_by": {
                "type": "string",
                "nullable": true,
                "enum": [
                  "manual",
                  "automatic",
                  "investigator",
                  null
                ],
                "description": "Pihak yang menetapkan status. `null` selama sesi belum diputuskan."
              },
              "decided_at": {
                "type": "string",
                "format": "date-time",
                "nullable": true
              },
              "automatic_status": {
                "type": "string",
                "nullable": true,
                "description": "Kesimpulan dari pemeriksaan platform itu sendiri, yang berbeda dari `status` setelah adanya keputusan manual."
              },
              "terminal_node_id": {
                "type": "string",
                "nullable": true,
                "description": "Node status alur kerja yang mengakhiri sesi, jika ada."
              },
              "actor": {
                "type": "object",
                "nullable": true,
                "description": "Peninjau yang membuat keputusan manual.",
                "properties": {
                  "user": {
                    "type": "string",
                    "nullable": true
                  },
                  "actor_type": {
                    "type": "string",
                    "nullable": true
                  }
                }
              },
              "warning_counts": {
                "type": "object",
                "description": "Peringatan per `log_type` (`error`, `warning`, `information`) dan `total`.",
                "additionalProperties": {
                  "type": "integer"
                }
              },
              "status_warnings": {
                "type": "array",
                "description": "Peringatan yang menetapkan status `Declined` atau `In Review`.",
                "items": {
                  "type": "object",
                  "properties": {
                    "risk": {
                      "type": "string"
                    },
                    "feature": {
                      "type": "string",
                      "nullable": true
                    },
                    "node_id": {
                      "type": "string",
                      "nullable": true
                    },
                    "log_type": {
                      "type": "string",
                      "nullable": true
                    },
                    "check_status": {
                      "type": "string",
                      "nullable": true
                    },
                    "source": {
                      "type": "string",
                      "description": "Daftar payload asal peringatan tersebut, misalnya `id_verifications`."
                    },
                    "short_description": {
                      "type": "string",
                      "nullable": true
                    }
                  }
                }
              }
            }
          },
          "linked_records": {
            "type": "object",
            "nullable": true,
            "description": "Ringkasan catatan lain yang ditautkan ke sesi. `null` jika tidak ada yang ditampilkan, dan untuk alur kerja yang menyatakan standar kepastian usia.",
            "properties": {
              "same_face": {
                "type": "object",
                "nullable": true,
                "description": "Orang lain yang wajahnya cocok dengan salah satu pencarian wajah sesi ini.",
                "properties": {
                  "count": {
                    "type": "integer"
                  },
                  "best_match": {
                    "type": "object",
                    "nullable": true,
                    "properties": {
                      "session_id": {
                        "type": "string",
                        "format": "uuid",
                        "nullable": true
                      },
                      "session_number": {
                        "type": "integer",
                        "nullable": true
                      },
                      "vendor_user_id": {
                        "type": "string",
                        "format": "uuid",
                        "nullable": true
                      },
                      "similarity_percentage": {
                        "type": "number",
                        "nullable": true
                      }
                    }
                  }
                }
              },
              "earlier_verifications": {
                "type": "object",
                "nullable": true,
                "properties": {
                  "count": {
                    "type": "integer"
                  },
                  "vendor_user_id": {
                    "type": "string",
                    "format": "uuid",
                    "nullable": true
                  }
                }
              },
              "networks": {
                "type": "object",
                "nullable": true,
                "properties": {
                  "count": {
                    "type": "integer"
                  },
                  "open": {
                    "type": "integer"
                  },
                  "dismissed": {
                    "type": "integer"
                  },
                  "items": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "network_id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "display_number": {
                          "type": "integer",
                          "nullable": true
                        },
                        "name": {
                          "type": "string"
                        },
                        "status": {
                          "type": "string"
                        },
                        "risk_score": {
                          "type": "number",
                          "nullable": true
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "workflow_id": {
            "type": "string",
            "format": "uuid",
            "description": "Pengidentifikasi stabil dari grup alur kerja yang menghasilkan sesi ini. Alur kerja memiliki versi — nilai ini mengidentifikasi alur kerja itu sendiri, bukan versi spesifiknya.",
            "nullable": true
          },
          "features": {
            "type": "array",
            "items": {
              "type": "string",
              "description": "Fitur dari sesi tersebut."
            },
            "description": "Daftar fitur verifikasi yang dikonfigurasi untuk sesi ini, sebagai nama tampilan: `ID_VERIFICATION`, `NFC`, `LIVENESS`, `FACE_MATCH`, `POA`, `PHONE`, `EMAIL_VERIFICATION`, `AML`, `IP_ANALYSIS`, `DATABASE_VALIDATION`, `QUESTIONNAIRE`, `AGE_ESTIMATION`, `FACE_SEARCH`, `GEOLOCATION` (Verifikasi lokasi) (Sesi Verifikasi Bisnis (KYB) menggunakan rangkaian fitur KYB: `KYB_REGISTRY`, `KYB_DOCUMENTS`, `KYB_KEY_PEOPLE`, `AML`, `PHONE`, `EMAIL_VERIFICATION`, `IP_ANALYSIS`, `QUESTIONNAIRE`). Dengan `include=events`, setiap entri menjadi objek `{feature, node_id}` dan bukan string biasa, dan fitur email diganti namanya: fitur tersebut muncul sebagai `EMAIL` dalam mode event, bukan `EMAIL_VERIFICATION` yang digunakan di sini."
          },
          "vendor_data": {
            "type": "string",
            "description": "Data vendor sesi.",
            "nullable": true
          },
          "metadata": {
            "type": "object",
            "description": "Metadata sesi.",
            "nullable": true
          },
          "expected_details": {
            "type": "object",
            "description": "Detail yang diharapkan yang diberikan saat pembuatan sesi — digunakan untuk validasi silang terhadap data yang diekstraksi (KYC) atau untuk mengisi otomatis pencarian registri perusahaan (KYB). Mengembalikan persis kunci-kunci yang diberikan; `null` jika tidak ada yang diberikan. Sesi KYC memuat kolom terkait orang; sesi Bisnis (KYB) memuat `company_name`, `registry_country`, dan `registration_number`.",
            "properties": {
              "first_name": {
                "type": "string",
                "description": "Nama depan pengguna. Misalnya, `John`."
              },
              "last_name": {
                "type": "string",
                "description": "Nama belakang pengguna. Misalnya, `Doe`."
              },
              "date_of_birth": {
                "type": "string",
                "format": "date",
                "description": "Tanggal lahir pengguna dengan format: YYYY-MM-DD. Misalnya, `1990-05-15`."
              },
              "gender": {
                "type": "string",
                "nullable": true,
                "enum": [
                  "M",
                  "F"
                ],
                "default": null,
                "description": "Jenis kelamin pengguna. Harus berupa 'M', 'F', atau null."
              },
              "nationality": {
                "type": "string",
                "description": "Kode negara ISO 3166-1 alpha-3 yang mewakili negara asal pemohon. Misalnya, `USA`."
              },
              "country": {
                "type": "string",
                "description": "Kode negara ISO 3166-1 alpha-3 yang mewakili negara dokumen Bukti Alamat, atau negara dokumen ID pemohon, yang mungkin berbeda dari kewarganegaraan. Misalnya, `GBR`."
              },
              "address": {
                "type": "string",
                "description": "Alamat dalam format yang dapat dibaca manusia, menyertakan sebanyak mungkin informasi. Misalnya, `123 Main St, San Francisco, CA 94105, USA`."
              },
              "identification_number": {
                "type": "string",
                "description": "Nomor dokumen, nomor pribadi, atau nomor pajak pengguna. Misalnya, `123456789`."
              },
              "ip_address": {
                "type": "string",
                "format": "ipv4",
                "description": "Alamat IP yang diharapkan untuk sesi. Jika alamat IP sebenarnya berbeda dari nilai ini, peringatan akan dicatat. Misalnya, `192.168.1.100`."
              },
              "expected_document_types": {
                "type": "array",
                "description": "Jenis dokumen yang dibatasi untuk langkah Verifikasi Identitas saat pembuatan sesi. Kosong/tidak diatur berarti tanpa pembatasan. Kode: `P` (paspor), `ID` (ID nasional), `DL` (surat izin mengemudi), `RP` (izin tinggal), `HIC` (kartu asuransi kesehatan), `TC` (kartu pajak), `SSC` (kartu jaminan sosial).",
                "items": {
                  "type": "string",
                  "enum": [
                    "P",
                    "ID",
                    "DL",
                    "RP",
                    "HIC",
                    "TC",
                    "SSC"
                  ]
                }
              },
              "id_country": {
                "type": "string",
                "nullable": true,
                "description": "Negara penerbit dokumen identitas yang diharapkan (ISO 3166-1 alpha-3), jika dibatasi pada saat pembuatan.",
                "example": "ESP"
              },
              "poa_country": {
                "type": "string",
                "nullable": true,
                "description": "Negara dokumen Bukti Alamat yang diharapkan (ISO 3166-1 alpha-3), jika dibatasi pada saat pembuatan.",
                "example": "ESP"
              },
              "company_name": {
                "type": "string",
                "description": "Nama resmi bisnis yang diharapkan. Khusus sesi Bisnis (KYB)."
              },
              "registry_country": {
                "type": "string",
                "description": "Negara registri yang diharapkan sebagai `XX` atau `XX-YY` (ISO 3166-1 alpha-2, secara opsional dengan subdivisi ISO 3166-2 untuk registri tingkat negara bagian, misalnya `US-CA`). Khusus sesi Bisnis (KYB)."
              },
              "registration_number": {
                "type": "string",
                "description": "Nomor registrasi perusahaan yang diharapkan. Hanya untuk sesi bisnis (KYB)."
              }
            },
            "nullable": true
          },
          "contact_details": {
            "type": "object",
            "description": "Detail kontak yang diberikan saat sesi dibuat (digunakan untuk email notifikasi, verifikasi telepon/email dengan data yang telah diisi sebelumnya, dan bahasa komunikasi). Bernilai `null` jika email maupun nomor telepon tidak diberikan.",
            "properties": {
              "email": {
                "type": "string",
                "description": "Alamat email pengguna (misalnya, \"john.doe@example.com\") yang akan digunakan selama langkah Verifikasi Email. Jika tidak diberikan, pengguna harus memberikannya selama alur verifikasi."
              },
              "email_lang": {
                "type": "string",
                "description": "Kode bahasa (ISO 639-1) untuk notifikasi email. Mengontrol bahasa semua komunikasi email (misalnya, \"en\", \"es\", \"fr\")."
              },
              "send_notification_emails": {
                "type": "boolean",
                "default": false,
                "description": "Jika true dan email disediakan, Didit mengirimkan email \"Verify your identity\" awal secara asinkron saat sesi Verifikasi Pengguna (KYC) atau Verifikasi Bisnis (KYB) dibuat. Didit juga mengirimkan notifikasi status verifikasi untuk sesi yang memerlukan peninjauan manual ke alamat email yang disediakan."
              },
              "phone": {
                "type": "string",
                "nullable": true,
                "description": "Nomor telepon pengguna dalam format E.164 jika tersedia (misalnya, +14155552671). Bernilai `null` jika hanya email yang diberikan saat pembuatan sesi. Catatan: Kolom ini mengembalikan nomor telepon asli yang diberikan saat pembuatan sesi. Jika nomor tersebut tidak valid, formatnya mungkin bukan format E.164."
              }
            },
            "nullable": true
          },
          "callback": {
            "type": "string",
            "format": "uri",
            "description": "URL callback sesi.",
            "nullable": true
          },
          "id_verifications": {
            "type": "array",
            "nullable": true,
            "description": "**Array laporan Verifikasi Identitas (OCR)** yang dihasilkan oleh langkah-langkah dokumen ID dalam graf alur kerja. Selalu berupa array JSON — baca `id_verifications[0]` dan lakukan iterasi jika alur kerja Anda dapat menjalankan lebih dari satu pemeriksaan ID (misalnya pemeriksaan utama ditambah step-up). Bernilai `null` sampai setidaknya satu langkah ID menghasilkan data. Setiap item adalah laporan lengkap, termasuk `node_id`, `status` tingkat fitur, kolom dokumen yang diekstrak, URL gambar, skor kualitas, MRZ, parsing alamat, pencocokan lintas-sesi, serta `warnings[]`.",
            "items": {
              "type": "object",
              "description": "Satu laporan Verifikasi Identitas - laporan lengkap untuk satu langkah Verifikasi Identitas tunggal. `verification_method` menunjukkan metode mana dari ketiga metode yang menghasilkannya (pengambilan dokumen, pencarian tanpa dokumen, atau masuk dengan dompet) dan blok bukti spesifik metode diisi sesuai dengannya.",
              "properties": {
                "node_id": {
                  "type": "string",
                  "description": "ID node graf alur kerja dari langkah OCR yang menghasilkan laporan ini."
                },
                "verification_method": {
                  "type": "string",
                  "enum": [
                    "document",
                    "id_lookup",
                    "wallet"
                  ],
                  "description": "Metode Verifikasi Identitas mana yang menghasilkan laporan ini. `document` - pengguna memfoto ID fisik (default, dan nilai pada setiap sesi yang dibuat sebelum metode lain tersedia). `id_lookup` - pengguna mengetikkan nomor identitas nasional mereka dan diperiksa terhadap registri pemerintah atau sumber otoritatif lainnya untuk negara tersebut (`id_lookup.source` menyebutkan sumbernya). `wallet` - pengguna masuk dengan identitas digital pemerintah atau bank."
                },
                "assurance": {
                  "type": "string",
                  "enum": [
                    "documentary",
                    "data_match",
                    "cryptographic"
                  ],
                  "description": "Tingkat jaminan yang diturunkan dari `verification_method`: `documentary` untuk dokumen yang diambil dan diperiksa, `data_match` untuk detail yang cocok dengan catatan yang disimpan oleh sumber yang ditanyakan, `cryptographic` untuk atribut yang diautentikasi dan ditandatangani oleh penyedia identitas."
                },
                "wallet_provider": {
                  "type": "string",
                  "nullable": true,
                  "description": "ID dompet katalog jika `verification_method` adalah `wallet` (`mitid`, `bankid_se`, `itsme`, ...). Selain itu bernilai `null`."
                },
                "fallback_from": {
                  "type": "object",
                  "nullable": true,
                  "description": "Alasan metode non-dokumen tidak menyelesaikan langkah ID. Ditetapkan saat pencarian atau proses masuk dompet gagal: pada verifikasi dokumen yang dilanjutkan pengguna ketika pengaturan fallback negara tersebut adalah `fallback_to_document` (`action` adalah `fallback_to_document`), atau pada laporan yang ditolak ketika nilainya adalah `decline`. `null` untuk kondisi lainnya.",
                  "properties": {
                    "method": {
                      "type": "string",
                      "enum": [
                        "id_lookup",
                        "wallet"
                      ],
                      "description": "Metode yang gagal."
                    },
                    "reason": {
                      "type": "string",
                      "description": "Hasil yang mengakhirinya, misalnya `no_match`, `provider_error`, `cancelled`, `timeout`."
                    },
                    "action": {
                      "type": "string",
                      "enum": [
                        "fallback_to_document",
                        "decline"
                      ],
                      "description": "Tindakan yang dikonfigurasi dan diambil: `fallback_to_document` atau `decline`."
                    }
                  }
                },
                "id_lookup": {
                  "type": "object",
                  "nullable": true,
                  "description": "Bukti registri. Hanya ada jika `verification_method` bernilai `id_lookup`; `null` jika tidak.",
                  "properties": {
                    "source": {
                      "type": "string",
                      "description": "Nama yang ditampilkan kepada pelanggan untuk sumber yang dikueri, misalnya `Department of Home Affairs` (registri pemerintah) atau `UK credit bureau and financial services records` (bukan registri pemerintah). Ini adalah satu-satunya pernyataan asal-usul untuk pencarian; jangan berasumsi ini adalah sumber pemerintah."
                    },
                    "checked_at": {
                      "type": "string",
                      "format": "date-time",
                      "nullable": true,
                      "description": "Waktu registri merespons."
                    },
                    "attempts": {
                      "type": "integer",
                      "description": "Nomor percobaan berbasis 1 yang menghasilkan laporan ini."
                    },
                    "max_attempts": {
                      "type": "integer",
                      "description": "Jumlah percobaan yang dikonfigurasi untuk negara tersebut (1 hingga 5, nilai bawaan 1)."
                    },
                    "outcome": {
                      "type": "string",
                      "enum": [
                        "match",
                        "partial_match",
                        "no_match",
                        "provider_error",
                        "format_rejected"
                      ],
                      "nullable": true,
                      "description": "Jawaban dari registri. Hanya `match`, `partial_match`, dan `no_match` yang diperhitungkan dalam kuota percobaan dan penagihan."
                    },
                    "comparison": {
                      "type": "array",
                      "description": "Satu baris per kolom yang dapat dibandingkan yang dijawab oleh sumber, ditambah satu baris per error sumber. Baris perbandingan menggunakan nama kolom yang dinormalisasi di bawah ini, bukan kunci kolom permintaan negara, karena beberapa kolom permintaan (nama depan dan belakang, atau salah satu alias pengenal) digabungkan menjadi satu perbandingan tunggal. Sumber yang gagal menambahkan baris dengan `field: \"provider\"` dan `result: \"error\"`, jadi baca `result` sebelum memperlakukan baris sebagai putusan kolom.",
                      "items": {
                        "type": "object",
                        "required": [
                          "field",
                          "label",
                          "provided",
                          "record",
                          "result"
                        ],
                        "properties": {
                          "field": {
                            "type": "string",
                            "enum": [
                              "identification_number",
                              "full_name",
                              "date_of_birth",
                              "address",
                              "provider"
                            ],
                            "description": "Kolom perbandingan yang dinormalisasi. `provider` bukan kolom pengguna: ini menandai baris kesalahan sumber."
                          },
                          "label": {
                            "type": "string",
                            "description": "Label tampilan untuk baris, misalnya `ID number`, `Full name`, `Provider`."
                          },
                          "provided": {
                            "type": "string",
                            "nullable": true,
                            "description": "Apa yang diketik oleh pengguna. Bernilai `null` pada baris kesalahan `provider`."
                          },
                          "record": {
                            "type": "string",
                            "nullable": true,
                            "description": "Data yang disimpan oleh sumber. Pada baris kesalahan `provider`, kolom ini memuat pesan kesalahan."
                          },
                          "result": {
                            "type": "string",
                            "enum": [
                              "match",
                              "partial",
                              "no_match",
                              "error"
                            ],
                            "description": "Hasil perbandingan per kolom. `error` hanya muncul pada baris `provider` dan berarti sumber tersebut tidak merespons; perlakukan ini sebagai bukti tentang kueri, bukan sebagai ketidakcocokan kolom."
                          }
                        }
                      }
                    },
                    "registry_portrait": {
                      "type": "string",
                      "format": "uri",
                      "nullable": true,
                      "description": "URL presigned berdurasi singkat ke potret yang dikembalikan sumber. Hanya empat registri pemerintah yang mengembalikannya (Afrika Selatan, Nigeria, Argentina, Panama)."
                    },
                    "face_match_score": {
                      "type": "number",
                      "nullable": true,
                      "description": "Swafoto dibandingkan dengan potret registri, 0-100. Hanya jika registri mengembalikan potret."
                    }
                  }
                },
                "wallet_verification": {
                  "type": "object",
                  "nullable": true,
                  "description": "Bukti kredensial. Hanya ada jika `verification_method` bernilai `wallet`; jika tidak, bernilai `null`.",
                  "properties": {
                    "provider": {
                      "type": "string",
                      "description": "ID dompet katalog, misalnya `mitid`."
                    },
                    "provider_name": {
                      "type": "string",
                      "nullable": true,
                      "description": "Nama dompet sebagaimana diketahui pengguna akhir, mis. `MitID`."
                    },
                    "issuing_authority": {
                      "type": "string",
                      "nullable": true,
                      "description": "Otoritas di balik dompet, misalnya `Danish Agency for Digital Government`."
                    },
                    "issuing_country": {
                      "type": "string",
                      "description": "Negara ISO 3166-1 alpha-3 tempat dompet ditawarkan."
                    },
                    "credential_type": {
                      "type": "string",
                      "nullable": true,
                      "description": "Kredensial yang diberikan oleh dompet, misalnya `person_identification`."
                    },
                    "level_of_assurance": {
                      "type": "string",
                      "enum": [
                        "low",
                        "substantial",
                        "high"
                      ],
                      "nullable": true,
                      "description": "Tingkat jaminan yang ditegaskan dompet. Masuk yang menegaskan kurang dari tingkat yang diminta akan gagal alih-alih diturunkan tingkatnya."
                    },
                    "verified_at": {
                      "type": "string",
                      "format": "date-time",
                      "nullable": true,
                      "description": "Waktu autentikasi dompet."
                    },
                    "signature_valid": {
                      "type": "boolean",
                      "nullable": true,
                      "description": "Apakah asersi yang ditandatangani dan dikembalikan oleh dompet tervalidasi."
                    },
                    "attributes": {
                      "type": "object",
                      "additionalProperties": true,
                      "description": "Atribut yang dibagikan dompet, dengan kunci seperti yang tercantum dalam entri katalog dompet."
                    },
                    "portrait": {
                      "type": "string",
                      "format": "uri",
                      "nullable": true,
                      "description": "URL presigned berdurasi singkat ke potret yang dibagikan dompet, jika dompet membagikannya."
                    },
                    "face_match_score": {
                      "type": "number",
                      "nullable": true,
                      "description": "Swafoto dibandingkan dengan potret dompet, 0-100, jika dompet membagikannya."
                    }
                  }
                },
                "status": {
                  "type": "string",
                  "enum": [
                    "Not Finished",
                    "Approved",
                    "Declined",
                    "In Review",
                    "Expired"
                  ],
                  "description": "Status tingkat fitur dari langkah verifikasi identitas ini. Tidak bergantung pada `status` sesi tingkat atas — sesi dapat mencapai keputusan keseluruhannya sementara fitur individual tetap `In Review`."
                },
                "document_type": {
                  "type": "string",
                  "description": "Jenis dokumen identitas"
                },
                "document_subtype": {
                  "type": "string",
                  "nullable": true,
                  "description": "Kode subtipe dokumen yang diterima dari pengaturan dokumen alur kerja, termasuk wilayah dokumen jika berlaku. Contoh: `ID_CARD_GENERIC`, `QUEENSLAND_DRIVER_LICENSE_GENERIC`."
                },
                "document_number": {
                  "type": "string",
                  "description": "Nomor identifikasi dokumen"
                },
                "personal_number": {
                  "type": "string",
                  "description": "Nomor identifikasi pribadi"
                },
                "portrait_image": {
                  "type": "string",
                  "format": "uri",
                  "description": "URL gambar potret"
                },
                "front_image": {
                  "type": "string",
                  "format": "uri",
                  "description": "URL gambar dokumen bagian depan"
                },
                "front_video": {
                  "type": "string",
                  "format": "uri",
                  "description": "URL video dokumen bagian depan"
                },
                "back_image": {
                  "type": "string",
                  "format": "uri",
                  "description": "URL gambar belakang dokumen"
                },
                "back_video": {
                  "type": "string",
                  "format": "uri",
                  "description": "URL video dokumen bagian belakang"
                },
                "full_front_image": {
                  "type": "string",
                  "format": "uri",
                  "description": "URL gambar lengkap dokumen bagian depan"
                },
                "full_back_image": {
                  "type": "string",
                  "format": "uri",
                  "description": "URL gambar lengkap dokumen bagian belakang"
                },
                "front_image_camera_front": {
                  "type": "string",
                  "format": "uri",
                  "description": "URL gambar dokumen bagian depan yang diambil dari kamera depan"
                },
                "back_image_camera_front": {
                  "type": "string",
                  "format": "uri",
                  "description": "URL gambar dokumen bagian belakang yang diambil dari kamera depan"
                },
                "date_of_birth": {
                  "type": "string",
                  "format": "date",
                  "description": "Tanggal lahir dari dokumen"
                },
                "age": {
                  "type": "integer",
                  "description": "Usia yang dihitung dari tanggal lahir"
                },
                "expiration_date": {
                  "type": "string",
                  "format": "date",
                  "description": "Tanggal kedaluwarsa dokumen"
                },
                "date_of_issue": {
                  "type": "string",
                  "format": "date",
                  "description": "Tanggal penerbitan dokumen"
                },
                "issuing_state": {
                  "type": "string",
                  "description": "Kode ISO negara bagian penerbit"
                },
                "issuing_state_name": {
                  "type": "string",
                  "description": "Nama lengkap negara bagian penerbit"
                },
                "first_name": {
                  "type": "string",
                  "description": "Nama depan dari dokumen"
                },
                "last_name": {
                  "type": "string",
                  "description": "Nama belakang dari dokumen"
                },
                "full_name": {
                  "type": "string",
                  "description": "Nama lengkap dari dokumen"
                },
                "gender": {
                  "type": "string",
                  "description": "Jenis kelamin dari dokumen"
                },
                "address": {
                  "type": "string",
                  "description": "Alamat mentah dari dokumen"
                },
                "formatted_address": {
                  "type": "string",
                  "description": "Alamat lengkap terformat"
                },
                "place_of_birth": {
                  "type": "string",
                  "description": "Tempat lahir dari dokumen"
                },
                "marital_status": {
                  "type": "string",
                  "description": "Status perkawinan dari dokumen"
                },
                "nationality": {
                  "type": "string",
                  "description": "Kode kewarganegaraan ISO"
                },
                "extra_fields": {
                  "type": "object",
                  "description": "Kolom dokumen tambahan. Mencakup atribut khusus dokumen (misalnya `dl_categories`, `blood_group`, `sponsor`, `employer`, `dl_class_code_b_from`, `dl_class_code_b_to`). Tanggal masa berlaku kelas surat izin mengemudi dikembalikan sebagai `dl_class_code_<class>_from` dan `dl_class_code_<class>_to`, serta kode pembatasan/informasi per kelas (misalnya kolom 12 lisensi UK) sebagai `dl_class_code_<class>_notes`. Jika dokumen memuat nama, alamat, atau tempat lahir dalam beberapa aksara, objek ini juga menyertakan versi aksara alternatif dari kolom-kolom tersebut. Pengaturan alur kerja `preferred_characters` (`latin` atau `non_latin`) mengatur aksara mana yang mengisi kolom tingkat atas (`first_name`, `last_name`, `full_name`, `address`, `place_of_birth`); aksara yang berlawanan masuk ke sini sebagai `first_name_non_latin` / `last_name_non_latin` / `full_name_non_latin` / `middle_name_non_latin` / `address_non_latin` / `place_of_birth_non_latin` (ketika `preferred_characters` adalah `latin`) atau dengan akhiran `_latin` (ketika `preferred_characters` adalah `non_latin`). Kunci hanya muncul jika OCR benar-benar mengekstrak nilai aksara alternatif nyata — kolom yang nilai alternatifnya berada dalam aksara yang sama dengan set pilihan (misalnya, kolom berlabel Kiril yang nilai OCR-nya kembali dalam homoglif Latin) akan dilewati. Ketika `preferred_characters` adalah `latin` tetapi dokumen hanya memuat teks non-Latin, Didit mentransliterasikan nilai yang diekstrak dan menampilkan `first_name_latin` / `last_name_latin` / dll. sebagai cadangan.",
                  "additionalProperties": true,
                  "properties": {
                    "dl_categories": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "blood_group": {
                      "type": "string",
                      "nullable": true
                    },
                    "first_name_non_latin": {
                      "type": "string",
                      "description": "Nama depan dalam aksara non-Latin ketika `preferred_characters=latin` dan versi non-Latin tersedia pada dokumen (mis. `Айна` untuk ID Kirgistan)."
                    },
                    "last_name_non_latin": {
                      "type": "string",
                      "description": "Nama belakang dalam aksara non-Latin ketika `preferred_characters=latin` dan versi non-Latin ada pada dokumen."
                    },
                    "middle_name_non_latin": {
                      "type": "string",
                      "description": "Nama tengah / patronimik dalam aksara non-Latin jika `preferred_characters=latin` dan versi non-Latin ada pada dokumen."
                    },
                    "full_name_non_latin": {
                      "type": "string",
                      "description": "Nama lengkap gabungan dalam aksara non-Latin. Direkonstruksi dari komponen individual saat nama depan dan belakang tersedia."
                    },
                    "address_non_latin": {
                      "type": "string",
                      "description": "Alamat dalam aksara non-Latin ketika `preferred_characters=latin` dan versi non-Latin ada pada dokumen."
                    },
                    "place_of_birth_non_latin": {
                      "type": "string",
                      "description": "Tempat lahir dalam aksara non-Latin saat `preferred_characters=latin` dan versi non-Latin ada pada dokumen."
                    },
                    "first_name_latin": {
                      "type": "string",
                      "description": "Nama depan dalam aksara Latin. Terisi ketika `preferred_characters=non_latin` dan versi Latin tersedia pada dokumen, atau — sebagai cadangan transliterasi — ketika `preferred_characters=latin` namun dokumen hanya memuat teks non-Latin."
                    },
                    "last_name_latin": {
                      "type": "string",
                      "description": "Nama belakang dalam aksara Latin. Aturan yang sama seperti `first_name_latin`."
                    },
                    "middle_name_latin": {
                      "type": "string",
                      "description": "Nama tengah / patronimik dalam aksara Latin. Aturan yang sama dengan `first_name_latin`."
                    },
                    "full_name_latin": {
                      "type": "string",
                      "description": "Nama lengkap gabungan dalam aksara Latin. Selalu direkonstruksi dari komponen individual saat nama depan dan belakang tersedia."
                    },
                    "address_latin": {
                      "type": "string",
                      "description": "Alamat dalam aksara Latin. Aturan yang sama seperti `first_name_latin`."
                    },
                    "place_of_birth_latin": {
                      "type": "string",
                      "description": "Tempat lahir dalam aksara Latin. Aturan yang sama seperti `first_name_latin`."
                    }
                  }
                },
                "mrz": {
                  "type": "object",
                  "nullable": true,
                  "description": "Kolom Zona Terbaca Mesin (MRZ) yang diurai dari dokumen. `null` jika tidak ada MRZ yang terdeteksi.",
                  "properties": {
                    "surname": {
                      "type": "string",
                      "example": "MARTINEZ<SANCHEZ"
                    },
                    "name": {
                      "type": "string",
                      "example": "ELENA"
                    },
                    "country": {
                      "type": "string",
                      "example": "ESP"
                    },
                    "nationality": {
                      "type": "string",
                      "example": "ESP"
                    },
                    "birth_date": {
                      "type": "string",
                      "example": "850315"
                    },
                    "expiry_date": {
                      "type": "string",
                      "example": "220821"
                    },
                    "sex": {
                      "type": "string",
                      "example": "F"
                    },
                    "document_type": {
                      "type": "string",
                      "example": "ID"
                    },
                    "document_number": {
                      "type": "string",
                      "example": "YZA123456"
                    },
                    "optional_data": {
                      "type": "string",
                      "example": "X9876543L"
                    },
                    "optional_data_2": {
                      "type": "string",
                      "example": ""
                    },
                    "birth_date_hash": {
                      "type": "string",
                      "example": "7"
                    },
                    "expiry_date_hash": {
                      "type": "string",
                      "example": "4"
                    },
                    "document_number_hash": {
                      "type": "string",
                      "example": "9"
                    },
                    "final_hash": {
                      "type": "string",
                      "example": "2"
                    },
                    "personal_number": {
                      "type": "string",
                      "example": "X9876543L"
                    },
                    "warnings": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "errors": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "mrz_type": {
                      "type": "string",
                      "example": "TD1"
                    },
                    "mrz_string": {
                      "type": "string",
                      "example": "IDESPMARTINEZ<SANCHEZ<<<<<<<<<<\nYZA123456<9ESP8503157F3208214<X9876543L<<<<<<<2\nMARTINEZ<SANCHEZ<<ELENA<<<<<<<<<<"
                    },
                    "mrz_key": {
                      "type": "string",
                      "example": "YZA123456985031573208214"
                    }
                  }
                },
                "parsed_address": {
                  "type": "object",
                  "description": "Detail alamat terstruktur",
                  "properties": {
                    "city": {
                      "type": "string"
                    },
                    "label": {
                      "type": "string"
                    },
                    "region": {
                      "type": "string"
                    },
                    "country": {
                      "type": "string",
                      "description": "Kode negara dua huruf"
                    },
                    "category": {
                      "type": "string",
                      "description": "Kategori alamat (misalnya, Residensial, Komersial)"
                    },
                    "street_1": {
                      "type": "string"
                    },
                    "street_2": {
                      "type": "string",
                      "nullable": true
                    },
                    "is_verified": {
                      "type": "boolean",
                      "description": "Apakah alamat telah diverifikasi"
                    },
                    "postal_code": {
                      "type": "string"
                    },
                    "raw_results": {
                      "type": "object",
                      "properties": {
                        "types": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "geometry": {
                          "type": "object",
                          "properties": {
                            "location": {
                              "type": "object",
                              "properties": {
                                "lat": {
                                  "type": "number"
                                },
                                "lng": {
                                  "type": "number"
                                }
                              }
                            },
                            "viewport": {
                              "type": "object",
                              "properties": {
                                "northeast": {
                                  "type": "object",
                                  "properties": {
                                    "lat": {
                                      "type": "number"
                                    },
                                    "lng": {
                                      "type": "number"
                                    }
                                  }
                                },
                                "southwest": {
                                  "type": "object",
                                  "properties": {
                                    "lat": {
                                      "type": "number"
                                    },
                                    "lng": {
                                      "type": "number"
                                    }
                                  }
                                }
                              }
                            },
                            "location_type": {
                              "type": "string"
                            }
                          }
                        },
                        "place_id": {
                          "type": "string"
                        },
                        "formatted_address": {
                          "type": "string"
                        },
                        "navigation_points": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "location": {
                                "type": "object",
                                "properties": {
                                  "latitude": {
                                    "type": "number"
                                  },
                                  "longitude": {
                                    "type": "number"
                                  }
                                }
                              }
                            }
                          }
                        },
                        "address_components": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "types": {
                                "type": "array",
                                "items": {
                                  "type": "string"
                                }
                              },
                              "long_name": {
                                "type": "string"
                              },
                              "short_name": {
                                "type": "string"
                              }
                            }
                          }
                        }
                      }
                    },
                    "address_type": {
                      "type": "string"
                    },
                    "document_location": {
                      "type": "object",
                      "properties": {
                        "latitude": {
                          "type": "number"
                        },
                        "longitude": {
                          "type": "number"
                        }
                      }
                    },
                    "formatted_address": {
                      "type": "string"
                    }
                  }
                },
                "extra_files": {
                  "type": "array",
                  "items": {
                    "type": "string",
                    "format": "uri"
                  },
                  "description": "File verifikasi dokumen tambahan"
                },
                "front_image_camera_front_face_match_score": {
                  "type": "number",
                  "nullable": true,
                  "description": "Skor pencocokan wajah antara potret yang diekstrak dari gambar dokumen bagian depan dan gambar kamera depan"
                },
                "back_image_camera_front_face_match_score": {
                  "type": "number",
                  "nullable": true,
                  "description": "Skor pencocokan wajah antara potret yang diekstrak dari gambar dokumen bagian belakang dan gambar kamera depan"
                },
                "document_selfie_face_matches": {
                  "type": "array",
                  "description": "Sesi sebelumnya atau entri daftar blokir wajah yang wajahnya cocok dengan swafoto yang diambil kamera depan selama pengambilan dokumen (Pencarian Wajah Silent Capture). Format entri sama seperti `liveness_checks[].matches`. `null` untuk sesi yang dibuat sebelum kolom ini ada atau ketika pencarian tidak dijalankan; array kosong ketika dijalankan dan tidak menemukan apa pun. `match_image_url` adalah URL presigned yang akan kedaluwarsa.",
                  "items": {
                    "type": "object",
                    "properties": {
                      "session_id": {
                        "type": "string",
                        "format": "uuid",
                        "nullable": true,
                        "description": "ID sesi wajah yang cocok. Bernilai `null` jika `source` adalah `imported`, `list_entry`, atau `retained_template`."
                      },
                      "session_number": {
                        "type": "integer",
                        "nullable": true
                      },
                      "similarity_percentage": {
                        "type": "number",
                        "description": "Kemiripan wajah antara kedua gambar, dibatasi pada rentang 0–100."
                      },
                      "vendor_data": {
                        "type": "string",
                        "nullable": true,
                        "description": "`vendor_data` dari sesi yang cocok atau Pengguna yang ditautkan untuk wajah yang diimpor dan templatnya dipertahankan."
                      },
                      "vendor_user_id": {
                        "type": "string",
                        "format": "uuid",
                        "nullable": true,
                        "description": "ID Pengguna yang ditautkan untuk kecocokan `imported` dan `retained_template` serta untuk kecocokan sesi yang ditautkan ke Pengguna. `null` untuk entri daftar dan sesi tanpa Pengguna."
                      },
                      "biometric_template_id": {
                        "type": "string",
                        "format": "uuid",
                        "nullable": true,
                        "description": "Id templat biometrik yang disimpan. Ditetapkan hanya jika `source` bernilai `retained_template`; jika tidak, bernilai `null`."
                      },
                      "verification_date": {
                        "type": "string",
                        "format": "date-time",
                        "nullable": true,
                        "description": "Waktu wajah yang cocok diambil, atau waktu templat yang disimpan dibuat. `null` untuk entri daftar."
                      },
                      "user_details": {
                        "type": "object",
                        "nullable": true,
                        "description": "Data identitas dari sesi yang cocok atau profil Pengguna yang diimpor. Selalu bernilai `null` untuk kecocokan `retained_template` dan `list_entry`.",
                        "properties": {
                          "full_name": {
                            "type": "string",
                            "nullable": true
                          },
                          "document_type": {
                            "type": "string",
                            "nullable": true
                          },
                          "document_number": {
                            "type": "string",
                            "nullable": true
                          }
                        }
                      },
                      "match_image_url": {
                        "type": "string",
                        "format": "uri",
                        "nullable": true,
                        "description": "Gambar referensi untuk pencocokan berbasis gambar. Selalu `null` untuk pencocokan `retained_template` karena templat yang disimpan tidak memuat gambar."
                      },
                      "status": {
                        "type": "string",
                        "nullable": true,
                        "description": "Status siklus hidup dari sesi yang cocok. `null` untuk sumber non-sesi."
                      },
                      "is_blocklisted": {
                        "type": "boolean",
                        "description": "Apakah wajah yang cocok ada di daftar blokir."
                      },
                      "is_allowlisted": {
                        "type": "boolean",
                        "description": "Apakah wajah yang cocok ada di daftar izin."
                      },
                      "api_service": {
                        "type": "string",
                        "nullable": true,
                        "description": "Layanan API mandiri dari sesi yang cocok (mis. `PASSIVE_LIVENESS`, `FACE_MATCH`); `null` untuk sesi alur kerja dan sumber non-sesi."
                      },
                      "source": {
                        "type": "string",
                        "enum": [
                          "session",
                          "imported",
                          "list_entry",
                          "retained_template"
                        ],
                        "description": "Asal wajah yang cocok: `session`, `imported` (unggahan wajah Pengguna), `list_entry` (daftar izin/blokir), atau `retained_template` (templat biometrik tanpa gambar yang disimpan pada Pengguna, tercantum di bawah `/v3/biometric-templates/`)."
                      }
                    }
                  },
                  "nullable": true
                },
                "front_image_quality_score": {
                  "type": "object",
                  "nullable": true,
                  "description": "Metrik kualitas untuk gambar depan dokumen. Setiap subskor berkisar dari 0 hingga 100.",
                  "properties": {
                    "focus_score": {
                      "type": "number",
                      "description": "Ketajaman gambar diukur melalui varians Laplacian lokal 10% teratas. Kuat terhadap dokumen dengan latar belakang seragam yang luas. Nilai yang lebih tinggi menunjukkan gambar yang lebih tajam dan tidak buram."
                    },
                    "brightness_score": {
                      "type": "number",
                      "description": "Seberapa baik pencahayaan gambar. Memberikan penalti pada gambar yang terlalu gelap atau terlalu terang, dengan kecerahan ideal di sekitar rentang menengah."
                    },
                    "brightness_issue": {
                      "type": "string",
                      "enum": [
                        "ok",
                        "too_dark",
                        "too_bright"
                      ],
                      "description": "Menunjukkan arah masalah kecerahan saat brightness_score rendah. 'ok' berarti kecerahan dapat diterima, 'too_dark' berarti gambar kurang cahaya, 'too_bright' berarti gambar terlalu terang."
                    },
                    "is_document_fully_visible": {
                      "type": "boolean",
                      "nullable": true,
                      "description": "true jika keempat sudut dokumen terlihat sepenuhnya di dalam bingkai gambar, false jika ada sudut yang terpotong. Null jika koordinat sudut tidak tersedia."
                    },
                    "resolution_score": {
                      "type": "number",
                      "description": "Resolusi efektif dari gambar berdasarkan jumlah piksel total."
                    },
                    "overall_score": {
                      "type": "number",
                      "description": "Komposit berbobot dari sub-skor (fokus 45%, kecerahan 30%, resolusi 25%)."
                    }
                  }
                },
                "back_image_quality_score": {
                  "type": "object",
                  "nullable": true,
                  "description": "Metrik kualitas untuk gambar belakang dokumen. Struktur yang sama seperti front_image_quality_score.",
                  "properties": {
                    "focus_score": {
                      "type": "number",
                      "description": "Ketajaman gambar diukur melalui varians Laplacian lokal 10% teratas. Kuat terhadap dokumen dengan latar belakang seragam yang luas. Nilai yang lebih tinggi menunjukkan gambar yang lebih tajam dan tidak buram."
                    },
                    "brightness_score": {
                      "type": "number",
                      "description": "Seberapa baik pencahayaan gambar. Memberikan penalti pada gambar yang terlalu gelap atau terlalu terang, dengan kecerahan ideal di sekitar rentang menengah."
                    },
                    "brightness_issue": {
                      "type": "string",
                      "enum": [
                        "ok",
                        "too_dark",
                        "too_bright"
                      ],
                      "description": "Menunjukkan arah masalah kecerahan saat brightness_score rendah. 'ok' berarti kecerahan dapat diterima, 'too_dark' berarti gambar kurang cahaya, 'too_bright' berarti gambar terlalu terang."
                    },
                    "is_document_fully_visible": {
                      "type": "boolean",
                      "nullable": true,
                      "description": "true jika keempat sudut dokumen terlihat sepenuhnya di dalam bingkai gambar, false jika ada sudut yang terpotong. Null jika koordinat sudut tidak tersedia."
                    },
                    "resolution_score": {
                      "type": "number",
                      "description": "Resolusi efektif dari gambar berdasarkan jumlah piksel total."
                    },
                    "overall_score": {
                      "type": "number",
                      "description": "Komposit berbobot dari sub-skor (fokus 45%, kecerahan 30%, resolusi 25%)."
                    }
                  }
                },
                "warnings": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "feature": {
                        "type": "string",
                        "enum": [
                          "ID_VERIFICATION",
                          "NFC",
                          "LIVENESS",
                          "FACEMATCH",
                          "PROOF_OF_ADDRESS",
                          "PHONE",
                          "EMAIL",
                          "AML",
                          "LOCATION",
                          "DATABASE_VALIDATION",
                          "QUESTIONNAIRE",
                          "DOCUMENT_AI",
                          "KYB_REGISTRY",
                          "KYB_DOCUMENTS",
                          "KYB_KEY_PEOPLE",
                          "GEOLOCATION",
                          "SIGNATURE"
                        ],
                        "description": "Fitur yang menghasilkan peringatan ini (misalnya, `ID_VERIFICATION`, `NFC`, `LIVENESS`). Nilai ini mengidentifikasi blok fitur tempat peringatan tersebut berada. Array peringatan setiap modul biasanya menggunakan nilai yang cocok dengan modulnya, tetapi enum di atas bersifat otoritatif di semua peringatan fitur pada payload keputusan."
                      },
                      "risk": {
                        "type": "string"
                      },
                      "additional_data": {
                        "type": "object",
                        "nullable": true,
                        "description": "Data kontekstual tambahan tentang peringatan"
                      },
                      "log_type": {
                        "type": "string",
                        "description": "Jenis log: informasi, peringatan, atau kesalahan"
                      },
                      "short_description": {
                        "type": "string"
                      },
                      "long_description": {
                        "type": "string"
                      },
                      "node_id": {
                        "type": "string",
                        "description": "ID node graf alur kerja yang menghasilkan peringatan ini (untuk alur kerja berbasis graf)"
                      }
                    }
                  },
                  "description": "Peringatan Verifikasi Dokumen"
                },
                "matches": {
                  "type": "array",
                  "description": "Dokumen yang cocok yang ditemukan selama deteksi duplikat/daftar blokir (hingga 5 kecocokan)",
                  "items": {
                    "type": "object",
                    "properties": {
                      "session_id": {
                        "type": "string",
                        "format": "uuid",
                        "description": "ID sesi dokumen yang cocok"
                      },
                      "session_number": {
                        "type": "integer",
                        "description": "Nomor sesi dari dokumen yang cocok"
                      },
                      "vendor_data": {
                        "type": "string",
                        "nullable": true,
                        "description": "Data vendor yang terkait dengan sesi yang cocok"
                      },
                      "verification_date": {
                        "type": "string",
                        "format": "date-time",
                        "description": "Tanggal saat sesi yang cocok diverifikasi"
                      },
                      "user_details": {
                        "type": "object",
                        "properties": {
                          "name": {
                            "type": "string",
                            "description": "Nama lengkap dari dokumen yang cocok"
                          },
                          "document_type": {
                            "type": "string",
                            "description": "Jenis dokumen yang cocok"
                          },
                          "document_number": {
                            "type": "string",
                            "description": "Nomor dokumen dari dokumen yang cocok"
                          }
                        }
                      },
                      "status": {
                        "type": "string",
                        "description": "Status sesi yang cocok"
                      },
                      "is_blocklisted": {
                        "type": "boolean",
                        "description": "Apakah dokumen yang cocok tercantum dalam daftar blokir"
                      },
                      "api_service": {
                        "type": "string",
                        "nullable": true,
                        "description": "Jenis layanan API dari sesi yang cocok"
                      },
                      "front_image_url": {
                        "type": "string",
                        "format": "uri",
                        "nullable": true,
                        "description": "URL gambar dokumen bagian depan dari dokumen yang cocok"
                      }
                    }
                  }
                },
                "document_liveness": {
                  "type": "object",
                  "nullable": true,
                  "description": "Skor liveness dokumen per jenis penipuan, dilaporkan baik ada peringatan yang terpicu maupun tidak, sehingga dokumen yang disetujui tetap dapat diaudit. `null` jika pemeriksaan tidak dijalankan.",
                  "properties": {
                    "portrait_replace": {
                      "type": "object",
                      "nullable": true,
                      "properties": {
                        "score": {
                          "type": "number",
                          "nullable": true,
                          "description": "Kemungkinan bahwa dokumen tersebut asli untuk jenis penipuan ini, 0-100 (lebih tinggi = lebih besar kemungkinan asli). Nilai terendah dari kedua sisi - nilai yang digunakan untuk keputusan. `null` jika kedua sisi tidak menghasilkan skor yang dapat digunakan."
                        },
                        "front": {
                          "type": "number",
                          "nullable": true,
                          "description": "Skor untuk sisi depan; `null` jika tidak diambil atau jika skor diabaikan."
                        },
                        "back": {
                          "type": "number",
                          "nullable": true,
                          "description": "Skor untuk sisi belakang; `null` jika tidak diambil atau jika skor diabaikan."
                        },
                        "decline_threshold": {
                          "type": "number",
                          "nullable": true,
                          "description": "Ambang batas penolakan yang disimpan saat dokumen ini dievaluasi. Pengeditan alur kerja setelahnya tidak mengubahnya. Null jika bukti evaluasi historis tidak tersedia."
                        },
                        "review_threshold": {
                          "type": "number",
                          "nullable": true,
                          "description": "Ambang batas peninjauan yang disimpan saat dokumen ini dievaluasi. Pengeditan alur kerja setelahnya tidak mengubahnya. Null jika bukti evaluasi historis tidak tersedia."
                        },
                        "bucket": {
                          "type": "string",
                          "nullable": true,
                          "enum": [
                            "approve",
                            "review",
                            "decline",
                            null
                          ],
                          "description": "Kategori jenis penipuan yang disimpan pada saat evaluasi. Bernilai null jika tidak ada skor yang dapat digunakan, pemeriksaan tidak diterapkan, atau bukti evaluasi historis tidak tersedia. Pengeditan alur kerja di kemudian hari tidak mengubahnya."
                        }
                      }
                    },
                    "printed_copy": {
                      "type": "object",
                      "nullable": true,
                      "properties": {
                        "score": {
                          "type": "number",
                          "nullable": true,
                          "description": "Kemungkinan bahwa dokumen tersebut asli untuk jenis penipuan ini, 0-100 (lebih tinggi = lebih besar kemungkinan asli). Nilai terendah dari kedua sisi - nilai yang digunakan untuk keputusan. `null` jika kedua sisi tidak menghasilkan skor yang dapat digunakan."
                        },
                        "front": {
                          "type": "number",
                          "nullable": true,
                          "description": "Skor untuk sisi depan; `null` jika tidak diambil atau jika skor diabaikan."
                        },
                        "back": {
                          "type": "number",
                          "nullable": true,
                          "description": "Skor untuk sisi belakang; `null` jika tidak diambil atau jika skor diabaikan."
                        },
                        "decline_threshold": {
                          "type": "number",
                          "nullable": true,
                          "description": "Ambang batas penolakan yang disimpan saat dokumen ini dievaluasi. Pengeditan alur kerja setelahnya tidak mengubahnya. Null jika bukti evaluasi historis tidak tersedia."
                        },
                        "review_threshold": {
                          "type": "number",
                          "nullable": true,
                          "description": "Ambang batas peninjauan yang disimpan saat dokumen ini dievaluasi. Pengeditan alur kerja setelahnya tidak mengubahnya. Null jika bukti evaluasi historis tidak tersedia."
                        },
                        "bucket": {
                          "type": "string",
                          "nullable": true,
                          "enum": [
                            "approve",
                            "review",
                            "decline",
                            null
                          ],
                          "description": "Kategori jenis penipuan yang disimpan pada saat evaluasi. Bernilai null jika tidak ada skor yang dapat digunakan, pemeriksaan tidak diterapkan, atau bukti evaluasi historis tidak tersedia. Pengeditan alur kerja di kemudian hari tidak mengubahnya."
                        }
                      }
                    },
                    "screen_replay": {
                      "type": "object",
                      "nullable": true,
                      "properties": {
                        "score": {
                          "type": "number",
                          "nullable": true,
                          "description": "Kemungkinan bahwa dokumen tersebut asli untuk jenis penipuan ini, 0-100 (lebih tinggi = lebih besar kemungkinan asli). Nilai terendah dari kedua sisi - nilai yang digunakan untuk keputusan. `null` jika kedua sisi tidak menghasilkan skor yang dapat digunakan."
                        },
                        "front": {
                          "type": "number",
                          "nullable": true,
                          "description": "Skor untuk sisi depan; `null` jika tidak diambil atau jika skor diabaikan."
                        },
                        "back": {
                          "type": "number",
                          "nullable": true,
                          "description": "Skor untuk sisi belakang; `null` jika tidak diambil atau jika skor diabaikan."
                        },
                        "decline_threshold": {
                          "type": "number",
                          "nullable": true,
                          "description": "Ambang batas penolakan yang disimpan saat dokumen ini dievaluasi. Pengeditan alur kerja setelahnya tidak mengubahnya. Null jika bukti evaluasi historis tidak tersedia."
                        },
                        "review_threshold": {
                          "type": "number",
                          "nullable": true,
                          "description": "Ambang batas peninjauan yang disimpan saat dokumen ini dievaluasi. Pengeditan alur kerja setelahnya tidak mengubahnya. Null jika bukti evaluasi historis tidak tersedia."
                        },
                        "bucket": {
                          "type": "string",
                          "nullable": true,
                          "enum": [
                            "approve",
                            "review",
                            "decline",
                            null
                          ],
                          "description": "Kategori jenis penipuan yang disimpan pada saat evaluasi. Bernilai null jika tidak ada skor yang dapat digunakan, pemeriksaan tidak diterapkan, atau bukti evaluasi historis tidak tersedia. Pengeditan alur kerja di kemudian hari tidak mengubahnya."
                        }
                      }
                    }
                  }
                },
                "address_validation": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/AddressValidationResult"
                    }
                  ],
                  "nullable": true,
                  "description": "Validasi Alamat dari alamat yang tertera pada dokumen ini: apakah alamat tersebut ada dan bentuk ternormalisasinya, sebagaimana yang dibaca dari dokumen (koreksi selanjutnya terhadap `address` tidak menjalankannya kembali). Hadir jika langkah Verifikasi Identitas ini mengaktifkan add-on Validasi Alamat; `null` jika tidak."
                },
                "region": {
                  "type": "string",
                  "nullable": true,
                  "description": "Wilayah atau negara bagian dari negara penerbit dokumen jika dokumen mencantumkannya."
                },
                "extracted_data": {
                  "type": "object",
                  "nullable": true,
                  "additionalProperties": true,
                  "description": "Cuplikan data yang diekstrak dari dokumen yang ditampilkan kepada pengguna untuk ditinjau, disimpan di samping nilai yang dikonfirmasi sehingga Anda dapat membandingkan apa yang terbaca dengan apa yang dikonfirmasi oleh pengguna. Bernilai `null` jika pengguna tidak diminta untuk meninjau."
                },
                "barcodes": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "additionalProperties": true
                  },
                  "description": "Data yang dibaca dari barcode dokumen. Kosong jika dokumen tidak memilikinya atau tidak ada yang terbaca."
                }
              }
            }
          },
          "nfc_skip_reason": {
            "type": "string",
            "nullable": true,
            "enum": [
              "USER_SKIPPED",
              "DOCUMENT_WITHOUT_CHIP",
              "CHIP_CERTIFICATE_UNAVAILABLE",
              "DEVICE_WITHOUT_NFC",
              "INTEGRATION_WITHOUT_NFC_ACCESS",
              "MRZ_KEY_UNAVAILABLE",
              "JPKI_UNAVAILABLE"
            ],
            "description": "Alasan verifikasi chip NFC tidak berjalan, terisi setiap kali alur kerja menyertakan langkah NFC. `null` selama NFC masih tertunda atau saat chip benar-benar terbaca. Nilai: `USER_SKIPPED` - pengguna memilih untuk melewati pada perangkat yang mendukung NFC (diizinkan oleh `allow_nfc_skip`); `DOCUMENT_WITHOUT_CHIP` - dokumen tidak memiliki chip NFC yang dapat dibaca (bukan dokumen elektronik ICAO 9303); `CHIP_CERTIFICATE_UNAVAILABLE` - sertifikat penandatanganan negara penerbit (CSCA) yang mencakup periode penerbitan dokumen tidak tersedia, sehingga tanda tangan chip tidak dapat diverifikasi; `DEVICE_WITHOUT_NFC` - perangkat melaporkan tidak adanya pembaca NFC; `INTEGRATION_WITHOUT_NFC_ACCESS` - verifikasi berjalan tanpa SDK native (misalnya di browser web), yang tidak memiliki akses ke pembaca NFC ponsel; `MRZ_KEY_UNAVAILABLE` - kunci akses chip tidak dapat diturunkan dari MRZ dokumen; `JPKI_UNAVAILABLE` - dokumen adalah Japan My Number Card, yang chip-nya dibaca melalui JPKI, dan JPKI tidak tersedia untuk verifikasi ini: JPKI tidak diaktifkan, atau SDK native aplikasi tidak dapat membaca My Number Card."
          },
          "nfc_verifications": {
            "type": "array",
            "nullable": true,
            "description": "**Array laporan NFC / ePassport** yang dihasilkan oleh langkah-langkah NFC dalam graf alur kerja. **Ini selalu berupa array JSON, bukan objek `nfc` tunggal** — baca `nfc_verifications[0]` dan lakukan iterasi jika alur kerja Anda dapat menjalankan NFC lebih dari sekali. Bernilai `null` sampai setidaknya satu langkah NFC menghasilkan data. Setiap item adalah laporan lengkap, termasuk `node_id`, `status` tingkat fitur, `chip_protocol`, `chip_data`, `authenticity` (integritas SOD + DG), `certificate_summary`, serta `warnings[]`. Japan My Number Card dibaca melalui JPKI dan bukan ICAO 9303: itemnya memiliki `chip_protocol: \"jpki\"`, membawa buktinya di bawah `jpki`, dan membiarkan kolom ICAO bernilai `null`. Ketika langkah NFC dilewati sebelum dapat ditawarkan (dokumen tanpa chip, sertifikat hilang, tidak ada kemampuan NFC yang dilaporkan, kunci MRZ tidak terbaca, JPKI tidak tersedia untuk My Number Card), ini tetap bernilai `null` dan `nfc_skip_reason` menjelaskan alasannya; pelewatan pada langkah itu sendiri (pengguna mengetuk opsi lewati, atau pemindai ternyata tidak tersedia saat pemindaian) tetap menghasilkan laporan dengan `is_nfc_skipped: true`.",
            "items": {
              "type": "object",
              "description": "Satu laporan NFC: laporan lengkap untuk satu kali pembacaan chip (chip ePassport atau eID ICAO 9303, atau Japan My Number Card yang dibaca melalui JPKI).",
              "properties": {
                "node_id": {
                  "type": "string",
                  "description": "ID node graf alur kerja dari langkah NFC yang menghasilkan laporan ini. Gunakan untuk mengorelasikan laporan dengan definisi alur kerja."
                },
                "status": {
                  "type": "string",
                  "enum": [
                    "Not Finished",
                    "Approved",
                    "Declined",
                    "In Review",
                    "Resub Requested"
                  ],
                  "description": "Status tingkat fitur dari langkah NFC ini. Tidak bergantung pada `status` sesi tingkat atas — sesi dapat mencapai keputusan keseluruhannya sementara fitur individual tetap `In Review`."
                },
                "is_nfc_skipped": {
                  "type": "boolean",
                  "description": "`true` saat langkah NFC ini secara eksplisit dilewati dan tidak dibaca; `skip_reason` menjelaskan alasannya."
                },
                "skip_reason": {
                  "type": "string",
                  "nullable": true,
                  "enum": [
                    "USER_SKIPPED",
                    "DOCUMENT_WITHOUT_CHIP",
                    "CHIP_CERTIFICATE_UNAVAILABLE",
                    "DEVICE_WITHOUT_NFC",
                    "INTEGRATION_WITHOUT_NFC_ACCESS",
                    "MRZ_KEY_UNAVAILABLE",
                    "JPKI_UNAVAILABLE"
                  ],
                  "description": "Alasan mengapa langkah NFC ini dilewati. Hanya diatur jika `is_nfc_skipped` bernilai `true`. Taksonomi yang sama dengan `nfc_skip_reason` tingkat sesi, yang juga mencakup kasus di mana NFC tidak pernah menghasilkan laporan sama sekali."
                },
                "chip_protocol": {
                  "type": "string",
                  "enum": [
                    "icao",
                    "jpki"
                  ],
                  "description": "Bagaimana langkah NFC membaca chip. `icao`: chip ePassport atau eID ICAO 9303, dibuka dengan kunci akses dari MRZ. `jpki`: Japan My Number Card, yang kartunya menandatangani tantangan satu kali setelah pemegang memasukkan PIN kartu di SDK native; hasilnya ada di bawah `jpki`. Juga diatur pada langkah yang dilewati, sehingga Anda dapat membedakan pembacaan My Number Card yang dilewati."
                },
                "jpki": {
                  "type": "object",
                  "nullable": true,
                  "description": "Hal yang dibuktikan oleh pembacaan Kartu My Number Jepang melalui JPKI. Ada ketika `chip_protocol` adalah `jpki` dan kartu dibaca. `null` untuk chip ICAO, untuk langkah yang dilewati, dan ketika langkah NFC ditutup tanpa ada kartu yang terbaca (kasus tersebut memunculkan `JPKI_SIGNATURE_INVALID`). Tidak pernah menyertakan sertifikat, nomor seri, tanda tangan, atau 12 digit My Number.",
                  "properties": {
                    "certificate_types": {
                      "type": "array",
                      "items": {
                        "type": "string",
                        "enum": [
                          "user_authentication",
                          "signature"
                        ]
                      },
                      "description": "Sertifikat kartu yang dibaca. `user_authentication` (PIN 4 digit) selalu dibaca; `signature` (PIN tanda tangan) dibaca saat pengaturan `jpki_request_attributes` pada node NFC aktif."
                    },
                    "chain_valid": {
                      "type": "boolean",
                      "description": "`true` jika setiap sertifikat yang dibaca memiliki rantai sertifikat ke otoritas sertifikasi JPKI, berada dalam masa berlakunya, dan merupakan sertifikat Kartu My Number dari tipenya."
                    },
                    "signature_valid": {
                      "type": "boolean",
                      "description": "`true` jika setiap tanda tangan yang dibuat kartu atas tantangan sekali pakai berhasil diverifikasi. Kartu hanya menandatangani setelah PIN-nya dimasukkan, sehingga hal ini membuktikan kepemilikan kartu dan pengetahuan tentang PIN tersebut."
                    },
                    "revocation_status": {
                      "type": "string",
                      "enum": [
                        "good",
                        "revoked",
                        "unchecked"
                      ],
                      "description": "`good` saat pemeriksaan pencabutan mengonfirmasi setiap sertifikat valid, `revoked` saat ada sertifikat yang dicabut (misalnya kartu dilaporkan hilang), `unchecked` saat tidak ada jawaban pencabutan yang tersedia. `unchecked` tidak pernah diperlakukan sebagai `good`: `jpki_revocation_unchecked_action` pada node NFC menentukan hasilnya (default `REVIEW`)."
                    },
                    "ca_generation": {
                      "type": "string",
                      "nullable": true,
                      "description": "Generasi otoritas sertifikasi JPKI yang menerbitkan sertifikat, misalnya `2023`. Bernilai `null` jika tidak ada sertifikat yang terhubung ke salah satunya."
                    },
                    "certificate_expires_at": {
                      "type": "string",
                      "format": "date-time",
                      "nullable": true,
                      "description": "Waktu kedaluwarsa paling awal di antara sertifikat yang dibaca."
                    },
                    "certificates": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "description": "Apa yang dibuktikan oleh satu sertifikat yang dibaca dari kartu. Tidak pernah sertifikat itu sendiri atau nomor serinya.",
                        "properties": {
                          "type": {
                            "type": "string",
                            "enum": [
                              "user_authentication",
                              "signature"
                            ],
                            "description": "Sertifikat kartu mana yang dijelaskan oleh entri ini."
                          },
                          "chain_valid": {
                            "type": "boolean",
                            "description": "`true` jika rantai sertifikat mengarah ke otoritas sertifikasi JPKI dari tipenya, berada dalam masa berlakunya, dan merupakan sertifikat Kartu My Number dari tipe tersebut."
                          },
                          "signature_valid": {
                            "type": "boolean",
                            "description": "`true` jika tanda tangan kartu atas tantangan sekali pakai terverifikasi terhadap sertifikat ini."
                          },
                          "ca_generation": {
                            "type": "string",
                            "nullable": true,
                            "description": "Generasi otoritas sertifikasi JPKI yang menerbitkan sertifikat, misalnya `2023`. Bernilai `null` jika tidak ada penerbit tepercaya yang ditemukan."
                          },
                          "not_valid_before": {
                            "type": "string",
                            "format": "date-time",
                            "nullable": true,
                            "description": "Awal masa berlaku sertifikat. `null` jika sertifikat tidak dapat dibaca."
                          },
                          "not_valid_after": {
                            "type": "string",
                            "format": "date-time",
                            "nullable": true,
                            "description": "Akhir masa berlaku sertifikat. `null` jika sertifikat tidak dapat dibaca."
                          },
                          "failure": {
                            "type": "string",
                            "nullable": true,
                            "enum": [
                              "unreadable_certificate",
                              "untrusted_issuer",
                              "expired",
                              "not_yet_valid",
                              "wrong_policy",
                              "key_usage",
                              null
                            ],
                            "description": "Alasan `chain_valid` bernilai `false`: `unreadable_certificate`, `untrusted_issuer` (tidak diterbitkan oleh otoritas sertifikasi JPKI untuk jenisnya), `expired`, `not_yet_valid`, `wrong_policy` (bukan sertifikat My Number Card untuk jenis tersebut) atau `key_usage` (kunci tidak dapat digunakan untuk menandatangani). `null` jika rantai valid."
                          }
                        }
                      },
                      "description": "Hasil per sertifikat, satu entri per sertifikat yang dibaca."
                    },
                    "attributes": {
                      "type": "object",
                      "nullable": true,
                      "description": "Data pemegang dari sertifikat tanda tangan, setelah rantainya valid. `null` jika sertifikat tanda tangan tidak diminta atau rantainya tidak terhubung ke otoritas sertifikasi JPKI.",
                      "properties": {
                        "full_name": {
                          "type": "string",
                          "nullable": true,
                          "description": "Nama sebagaimana terdaftar, biasanya dalam aksara Jepang."
                        },
                        "date_of_birth": {
                          "type": "string",
                          "format": "date",
                          "nullable": true,
                          "description": "Tanggal lahir, `YYYY-MM-DD`. `null` jika tanggal yang terdaftar tidak lengkap."
                        },
                        "gender": {
                          "type": "string",
                          "nullable": true,
                          "enum": [
                            "M",
                            "F",
                            null
                          ],
                          "description": "`M`, `F`, atau `null` ketika tidak terdaftar."
                        },
                        "address": {
                          "type": "string",
                          "nullable": true,
                          "description": "Alamat terdaftar."
                        },
                        "name_substitute_characters": {
                          "type": "string",
                          "nullable": true,
                          "description": "String posisi yang menandai karakter `full_name` yang diganti dengan pengganti karena karakter asli berada di luar kumpulan karakter standar. `null` jika tidak ada yang diganti."
                        },
                        "address_substitute_characters": {
                          "type": "string",
                          "nullable": true,
                          "description": "String posisi yang menandai karakter pengganti dalam `address`, seperti halnya `name_substitute_characters`."
                        }
                      }
                    },
                    "attributes_match_ocr": {
                      "type": "boolean",
                      "nullable": true,
                      "description": "`true` jika atribut cocok dengan data yang dibaca dari foto kartu yang sama, `false` jika ada atribut yang berbeda (`JPKI_AND_OCR_DATA_NOT_SAME`), `null` jika tidak ada yang dapat dibandingkan, termasuk setiap kali `attributes` bernilai `null`."
                    },
                    "mismatched_attributes": {
                      "type": "array",
                      "items": {
                        "type": "string",
                        "enum": [
                          "full_name",
                          "date_of_birth",
                          "gender",
                          "address"
                        ]
                      },
                      "description": "Nama atribut yang berbeda dari data foto, tidak pernah nilainya. Kosong jika semua yang dibandingkan cocok."
                    }
                  }
                },
                "portrait_image": {
                  "type": "string",
                  "format": "uri",
                  "nullable": true,
                  "description": "URL presigned ke potret yang dibaca dari chip (ICAO DG2). `null` untuk pembacaan JPKI (`chip_protocol: \"jpki\"`) dan untuk langkah yang dilewati."
                },
                "signature_image": {
                  "type": "string",
                  "format": "uri",
                  "nullable": true,
                  "description": "URL presigned ke gambar tanda tangan pemegang yang dibaca dari chip (ICAO DG7), jika chip menyimpannya. `null` untuk pembacaan JPKI (`chip_protocol: \"jpki\"`) dan untuk langkah yang dilewati."
                },
                "chip_data": {
                  "type": "object",
                  "nullable": true,
                  "description": "Data pribadi yang diurai dari Grup Data dari chip ICAO. Bernilai `null` untuk pembacaan JPKI (`chip_protocol: \"jpki\"`) dan untuk langkah yang dilewati.",
                  "properties": {
                    "document_type": {
                      "type": "string"
                    },
                    "issuing_country": {
                      "type": "string"
                    },
                    "document_number": {
                      "type": "string"
                    },
                    "expiration_date": {
                      "type": "string",
                      "format": "date"
                    },
                    "first_name": {
                      "type": "string"
                    },
                    "last_name": {
                      "type": "string"
                    },
                    "birth_date": {
                      "type": "string",
                      "format": "date"
                    },
                    "gender": {
                      "type": "string"
                    },
                    "nationality": {
                      "type": "string"
                    },
                    "address": {
                      "type": "string"
                    },
                    "place_of_birth": {
                      "type": "string"
                    }
                  }
                },
                "authenticity": {
                  "type": "object",
                  "nullable": true,
                  "description": "Autentikasi pasif ICAO: tanda tangan SOD (`sod_integrity`) dan hash Data Group (`dg_integrity`). `null` untuk pembacaan JPKI, yang melaporkan buktinya pada `jpki`.",
                  "properties": {
                    "sod_integrity": {
                      "type": "boolean"
                    },
                    "dg_integrity": {
                      "type": "boolean"
                    }
                  }
                },
                "certificate_summary": {
                  "type": "object",
                  "nullable": true,
                  "description": "Ringkasan Sertifikat Penanda Tangan Dokumen ICAO. `null` untuk pembacaan JPKI (`chip_protocol: \"jpki\"`) dan untuk langkah yang dilewati.",
                  "properties": {
                    "issuer": {
                      "type": "string"
                    },
                    "subject": {
                      "type": "string"
                    },
                    "serial_number": {
                      "type": "string"
                    },
                    "not_valid_after": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "not_valid_before": {
                      "type": "string",
                      "format": "date-time"
                    }
                  }
                },
                "warnings": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "feature": {
                        "type": "string",
                        "enum": [
                          "ID_VERIFICATION",
                          "NFC",
                          "LIVENESS",
                          "FACEMATCH",
                          "PROOF_OF_ADDRESS",
                          "PHONE",
                          "EMAIL",
                          "AML",
                          "LOCATION",
                          "DATABASE_VALIDATION",
                          "QUESTIONNAIRE",
                          "DOCUMENT_AI",
                          "KYB_REGISTRY",
                          "KYB_DOCUMENTS",
                          "KYB_KEY_PEOPLE",
                          "GEOLOCATION",
                          "SIGNATURE"
                        ],
                        "description": "Fitur yang menghasilkan peringatan ini. Nilai ini mengidentifikasi blok fitur tempat peringatan tersebut berada. Array peringatan setiap modul biasanya menggunakan nilai yang cocok dengan modulnya (misalnya `PHONE` di dalam `phone_verifications[].warnings`), tetapi enum di atas bersifat otoritatif di semua peringatan fitur pada payload keputusan."
                      },
                      "risk": {
                        "type": "string"
                      },
                      "additional_data": {
                        "type": "object",
                        "nullable": true
                      },
                      "log_type": {
                        "type": "string"
                      },
                      "short_description": {
                        "type": "string"
                      },
                      "long_description": {
                        "type": "string"
                      },
                      "node_id": {
                        "type": "string",
                        "description": "ID node graf alur kerja yang menghasilkan peringatan ini"
                      }
                    }
                  }
                }
              }
            }
          },
          "liveness_checks": {
            "type": "array",
            "nullable": true,
            "description": "**Array laporan liveness** yang dihasilkan oleh langkah-langkah liveness dalam graf alur kerja. Selalu berupa array JSON — bukan objek `liveness` tunggal. Bernilai `null` sampai setidaknya satu langkah liveness menghasilkan data. Setiap item adalah laporan lengkap, termasuk `node_id`, `status` tingkat fitur, `method`, `score`, `reference_image`, `video_url`, `age_estimation` opsional, `matches[]` lintas-sesi, serta `warnings[]`.",
            "items": {
              "type": "object",
              "description": "Satu laporan liveness — laporan lengkap untuk satu kali proses liveness.",
              "properties": {
                "node_id": {
                  "type": "string",
                  "description": "ID node graf alur kerja dari langkah Deteksi Liveness yang menghasilkan laporan ini."
                },
                "status": {
                  "type": "string",
                  "enum": [
                    "Not Finished",
                    "Approved",
                    "Declined",
                    "In Review",
                    "Resub Requested"
                  ],
                  "description": "Status tingkat fitur dari langkah liveness ini. Tidak bergantung pada `status` sesi tingkat atas — sesi dapat mencapai keputusan keseluruhannya sementara fitur individual tetap `In Review`."
                },
                "method": {
                  "type": "string",
                  "description": "Metode yang digunakan untuk deteksi liveness"
                },
                "score": {
                  "type": "number",
                  "description": "Skor keyakinan dari pemeriksaan liveness"
                },
                "reference_image": {
                  "type": "string",
                  "format": "uri",
                  "description": "URL gambar referensi yang digunakan"
                },
                "video_url": {
                  "type": "string",
                  "format": "uri",
                  "description": "URL video pemeriksaan liveness"
                },
                "age_estimation": {
                  "type": "number",
                  "description": "Usia hasil estimasi orang tersebut"
                },
                "matches": {
                  "type": "array",
                  "description": "Wajah serupa yang ditemukan oleh pencarian wajah duplikat (kecocokan teratas, entri daftar blokir/daftar izin terlebih dahulu). Kolom `source` pada setiap entri memberi tahu Anda dari mana wajah yang cocok berasal: `session` (sesi verifikasi lain), `imported` (wajah yang diunggah untuk pengguna vendor), `list_entry` (wajah daftar izin/blokir yang dikelola organisasi), atau `retained_template` (templat biometrik tanpa gambar yang disimpan pada Pengguna, tercantum di bawah `/v3/biometric-templates/`). `session_id`, `session_number`, `status`, dan `api_service` bernilai `null` untuk sumber selain sesi. Kecocokan `imported` tetap mengisi `vendor_data`, `verification_date`, dan — jika pengguna vendor memiliki nama yang tercatat — `user_details` (hanya dengan `full_name`) dari rekaman pengguna vendor; kecocokan `retained_template` mengisi `vendor_user_id`, `vendor_data`, `biometric_template_id`, dan `verification_date`, sedangkan kolom gambar dan identitasnya bernilai `null`; kecocokan `list_entry` mengembalikan semua kolom ini sebagai `null`.",
                  "items": {
                    "type": "object",
                    "properties": {
                      "session_id": {
                        "type": "string",
                        "format": "uuid",
                        "nullable": true,
                        "description": "ID sesi wajah yang cocok. Bernilai `null` jika `source` adalah `imported`, `list_entry`, atau `retained_template`."
                      },
                      "session_number": {
                        "type": "integer",
                        "nullable": true
                      },
                      "similarity_percentage": {
                        "type": "number",
                        "description": "Kemiripan wajah antara kedua gambar, dibatasi pada rentang 0–100."
                      },
                      "vendor_data": {
                        "type": "string",
                        "nullable": true,
                        "description": "`vendor_data` dari sesi yang cocok atau Pengguna yang ditautkan untuk wajah yang diimpor dan templatnya dipertahankan."
                      },
                      "vendor_user_id": {
                        "type": "string",
                        "format": "uuid",
                        "nullable": true,
                        "description": "ID Pengguna yang ditautkan untuk kecocokan `imported` dan `retained_template` serta untuk kecocokan sesi yang ditautkan ke Pengguna. `null` untuk entri daftar dan sesi tanpa Pengguna."
                      },
                      "biometric_template_id": {
                        "type": "string",
                        "format": "uuid",
                        "nullable": true,
                        "description": "Id templat biometrik yang disimpan. Ditetapkan hanya jika `source` bernilai `retained_template`; jika tidak, bernilai `null`."
                      },
                      "verification_date": {
                        "type": "string",
                        "format": "date-time",
                        "nullable": true,
                        "description": "Waktu wajah yang cocok diambil, atau waktu templat yang disimpan dibuat. `null` untuk entri daftar."
                      },
                      "user_details": {
                        "type": "object",
                        "nullable": true,
                        "description": "Data identitas dari sesi yang cocok atau profil Pengguna yang diimpor. Selalu bernilai `null` untuk kecocokan `retained_template` dan `list_entry`.",
                        "properties": {
                          "full_name": {
                            "type": "string",
                            "nullable": true
                          },
                          "document_type": {
                            "type": "string",
                            "nullable": true
                          },
                          "document_number": {
                            "type": "string",
                            "nullable": true
                          }
                        }
                      },
                      "match_image_url": {
                        "type": "string",
                        "format": "uri",
                        "nullable": true,
                        "description": "Gambar referensi untuk pencocokan berbasis gambar. Selalu `null` untuk pencocokan `retained_template` karena templat yang disimpan tidak memuat gambar."
                      },
                      "status": {
                        "type": "string",
                        "nullable": true,
                        "description": "Status siklus hidup dari sesi yang cocok. `null` untuk sumber non-sesi."
                      },
                      "is_blocklisted": {
                        "type": "boolean",
                        "description": "Apakah wajah yang cocok ada di daftar blokir."
                      },
                      "is_allowlisted": {
                        "type": "boolean",
                        "description": "Apakah wajah yang cocok ada di daftar izin."
                      },
                      "api_service": {
                        "type": "string",
                        "nullable": true,
                        "description": "Layanan API mandiri dari sesi yang cocok (mis. `PASSIVE_LIVENESS`, `FACE_MATCH`); `null` untuk sesi alur kerja dan sumber non-sesi."
                      },
                      "source": {
                        "type": "string",
                        "enum": [
                          "session",
                          "imported",
                          "list_entry",
                          "retained_template"
                        ],
                        "description": "Asal wajah yang cocok: `session`, `imported` (unggahan wajah Pengguna), `list_entry` (daftar izin/blokir), atau `retained_template` (templat biometrik tanpa gambar yang disimpan pada Pengguna, tercantum di bawah `/v3/biometric-templates/`)."
                      }
                    }
                  }
                },
                "warnings": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "feature": {
                        "type": "string",
                        "enum": [
                          "ID_VERIFICATION",
                          "NFC",
                          "LIVENESS",
                          "FACEMATCH",
                          "PROOF_OF_ADDRESS",
                          "PHONE",
                          "EMAIL",
                          "AML",
                          "LOCATION",
                          "DATABASE_VALIDATION",
                          "QUESTIONNAIRE",
                          "DOCUMENT_AI",
                          "KYB_REGISTRY",
                          "KYB_DOCUMENTS",
                          "KYB_KEY_PEOPLE",
                          "GEOLOCATION",
                          "SIGNATURE"
                        ],
                        "description": "Fitur yang menghasilkan peringatan ini. Nilai ini mengidentifikasi blok fitur tempat peringatan tersebut berada. Array peringatan setiap modul biasanya menggunakan nilai yang cocok dengan modulnya (misalnya `PHONE` di dalam `phone_verifications[].warnings`), tetapi enum di atas bersifat otoritatif di semua peringatan fitur pada payload keputusan."
                      },
                      "risk": {
                        "type": "string"
                      },
                      "additional_data": {
                        "type": "object",
                        "nullable": true
                      },
                      "log_type": {
                        "type": "string"
                      },
                      "short_description": {
                        "type": "string"
                      },
                      "long_description": {
                        "type": "string"
                      },
                      "node_id": {
                        "type": "string",
                        "description": "ID node graf alur kerja yang menghasilkan peringatan ini"
                      }
                    }
                  }
                },
                "face_quality": {
                  "type": "number",
                  "nullable": true,
                  "description": "Skor kualitas gambar wajah (0-100%). Hanya tersedia untuk liveness pasif."
                },
                "face_luminance": {
                  "type": "number",
                  "nullable": true,
                  "description": "Skor luminansi/kecerahan wajah (0-100%). Hanya tersedia untuk liveness pasif."
                }
              }
            }
          },
          "face_matches": {
            "type": "array",
            "nullable": true,
            "description": "**Array laporan Pencocokan Wajah** yang dihasilkan oleh langkah-langkah pencocokan wajah dalam graf alur kerja. Selalu berupa array JSON — bukan objek `face_match` tunggal. Bernilai `null` sampai setidaknya satu langkah pencocokan wajah menghasilkan data. Setiap item adalah laporan lengkap, termasuk `node_id`, `status` tingkat fitur, `score` kemiripan, `source_image`, `target_image`, serta `warnings[]`.",
            "items": {
              "type": "object",
              "description": "Satu laporan pencocokan wajah — laporan lengkap.",
              "properties": {
                "node_id": {
                  "type": "string",
                  "description": "ID node graf alur kerja dari langkah pencocokan wajah yang menghasilkan laporan ini."
                },
                "status": {
                  "type": "string",
                  "enum": [
                    "Not Finished",
                    "Approved",
                    "Declined",
                    "In Review",
                    "Resub Requested"
                  ],
                  "description": "Status tingkat fitur dari langkah pencocokan wajah ini. Tidak bergantung pada `status` sesi tingkat atas — sesi dapat mencapai keputusan keseluruhannya sementara fitur individual tetap `In Review`."
                },
                "score": {
                  "type": "number",
                  "description": "Skor keyakinan dari Pencocokan Wajah"
                },
                "source_image_session_id": {
                  "type": "string",
                  "format": "uuid",
                  "nullable": true,
                  "description": "ID sesi tempat potret sumber (referensi) disimpan. Dalam alur autentikasi biometrik, ini adalah ID sesi itu sendiri (potret yang dikirimkan disimpan di bawah sesi baru). Bernilai `null` jika gambar sumber adalah potret dokumen dari sesi yang sama."
                },
                "source_image": {
                  "type": "string",
                  "format": "uri",
                  "description": "URL gambar sumber yang digunakan untuk perbandingan"
                },
                "target_image": {
                  "type": "string",
                  "format": "uri",
                  "description": "URL gambar target yang digunakan untuk perbandingan"
                },
                "warnings": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "feature": {
                        "type": "string",
                        "enum": [
                          "ID_VERIFICATION",
                          "NFC",
                          "LIVENESS",
                          "FACEMATCH",
                          "PROOF_OF_ADDRESS",
                          "PHONE",
                          "EMAIL",
                          "AML",
                          "LOCATION",
                          "DATABASE_VALIDATION",
                          "QUESTIONNAIRE",
                          "DOCUMENT_AI",
                          "KYB_REGISTRY",
                          "KYB_DOCUMENTS",
                          "KYB_KEY_PEOPLE",
                          "GEOLOCATION",
                          "SIGNATURE"
                        ],
                        "description": "Fitur yang menghasilkan peringatan ini. Nilai ini mengidentifikasi blok fitur tempat peringatan tersebut berada. Array peringatan setiap modul biasanya menggunakan nilai yang cocok dengan modulnya (misalnya `PHONE` di dalam `phone_verifications[].warnings`), tetapi enum di atas bersifat otoritatif di semua peringatan fitur pada payload keputusan."
                      },
                      "risk": {
                        "type": "string"
                      },
                      "additional_data": {
                        "type": "object",
                        "nullable": true
                      },
                      "log_type": {
                        "type": "string"
                      },
                      "short_description": {
                        "type": "string"
                      },
                      "long_description": {
                        "type": "string"
                      },
                      "node_id": {
                        "type": "string",
                        "description": "ID node graf alur kerja yang menghasilkan peringatan ini"
                      }
                    }
                  },
                  "description": "Peringatan verifikasi pencocokan wajah"
                },
                "face_coverage": {
                  "type": "object",
                  "nullable": true,
                  "description": "Apakah mata, mulut, dan wajah tertutup pada gambar yang diambil. Hanya dikembalikan oleh `GET /v3/session/{sessionId}/decision/`; ini bukan bagian dari payload webhook. `null` jika tidak ada hasil pembacaan penutupan.",
                  "properties": {
                    "eyes": {
                      "type": "object",
                      "properties": {
                        "covered": {
                          "type": "boolean",
                          "nullable": true
                        },
                        "calibrated": {
                          "type": "boolean",
                          "nullable": true,
                          "description": "`false` berarti pembacaan tersebut hanya bukti bayangan dan tidak ada peringatan yang menindaklanjutinya."
                        },
                        "visibility_score": {
                          "type": "number",
                          "nullable": true
                        }
                      }
                    },
                    "mouth": {
                      "type": "object",
                      "properties": {
                        "covered": {
                          "type": "boolean",
                          "nullable": true
                        },
                        "calibrated": {
                          "type": "boolean",
                          "nullable": true,
                          "description": "`false` berarti pembacaan tersebut hanya bukti bayangan dan tidak ada peringatan yang menindaklanjutinya."
                        },
                        "visibility_score": {
                          "type": "number",
                          "nullable": true
                        }
                      }
                    },
                    "face": {
                      "type": "object",
                      "properties": {
                        "covered": {
                          "type": "boolean",
                          "nullable": true
                        },
                        "calibrated": {
                          "type": "boolean",
                          "nullable": true,
                          "description": "`false` berarti pembacaan tersebut hanya bukti bayangan dan tidak ada peringatan yang menindaklanjutinya."
                        },
                        "visibility_score": {
                          "type": "number",
                          "nullable": true
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "phone_verifications": {
            "type": "array",
            "nullable": true,
            "description": "**Array laporan Verifikasi Telepon** — selalu berupa array JSON, bukan objek `phone` tunggal. Bernilai `null` sampai setidaknya satu langkah telepon menghasilkan data. Setiap item adalah laporan lengkap, termasuk `node_id`, `status` tingkat fitur, nomor telepon dan metadata negara, `lifecycle[]`, `matches[]`, serta `warnings[]`.",
            "items": {
              "type": "object",
              "properties": {
                "node_id": {
                  "type": "string",
                  "description": "Pengenal unik untuk langkah telepon ini di dalam graf alur kerja."
                },
                "status": {
                  "type": "string",
                  "description": "Status tingkat fitur dari langkah verifikasi telepon ini. Tidak bergantung pada `status` sesi tingkat atas — sesi dapat mencapai keputusan keseluruhannya sementara fitur individual tetap `In Review`.",
                  "enum": [
                    "Not Finished",
                    "Approved",
                    "Declined",
                    "In Review",
                    "Expired"
                  ]
                },
                "phone_number_prefix": {
                  "type": "string",
                  "description": "Prefiks kode panggilan negara"
                },
                "phone_number": {
                  "type": "string",
                  "description": "Nomor telepon tanpa kode negara"
                },
                "full_number": {
                  "type": "string",
                  "description": "Nomor telepon lengkap dengan awalan negara"
                },
                "country_code": {
                  "type": "string",
                  "description": "Kode negara dua huruf (ISO 3166-1 alpha-2)"
                },
                "country_name": {
                  "type": "string",
                  "description": "Nama lengkap negara"
                },
                "carrier": {
                  "type": "object",
                  "properties": {
                    "name": {
                      "type": "string",
                      "description": "Nama operator telepon"
                    },
                    "type": {
                      "type": "string",
                      "description": "Jenis sambungan telepon (seluler, telepon tetap, dll.)"
                    }
                  }
                },
                "is_disposable": {
                  "type": "boolean",
                  "description": "Apakah nomor telepon berasal dari layanan sekali pakai"
                },
                "is_virtual": {
                  "type": "boolean",
                  "description": "Apakah nomor telepon bersifat virtual"
                },
                "verification_method": {
                  "type": "string",
                  "description": "Metode yang digunakan untuk memverifikasi nomor telepon"
                },
                "verification_attempts": {
                  "type": "integer",
                  "description": "Jumlah percobaan verifikasi yang dilakukan"
                },
                "verified_at": {
                  "type": "string",
                  "format": "date-time",
                  "description": "Cap waktu saat telepon diverifikasi"
                },
                "lifecycle": {
                  "type": "array",
                  "description": "Daftar kronologis event dalam siklus hidup verifikasi telepon.",
                  "items": {
                    "type": "object",
                    "properties": {
                      "type": {
                        "type": "string"
                      },
                      "timestamp": {
                        "type": "string",
                        "format": "date-time"
                      },
                      "details": {
                        "type": "object",
                        "nullable": true,
                        "description": "Payload khusus event. Event kirim memuat `status`, `reason`, `channel`, `actual_channel`; event pengiriman memuat `channel`, `status`; event pemeriksaan kode memuat `code_tried`, `status`; event status akhir memuat `reason` — atau `null` jika tidak ada alasan untuk dilaporkan (misalnya `PHONE_VERIFICATION_APPROVED`).",
                        "properties": {
                          "status": {
                            "type": "string"
                          },
                          "reason": {
                            "type": "string",
                            "nullable": true
                          },
                          "channel": {
                            "type": "string",
                            "nullable": true
                          },
                          "actual_channel": {
                            "type": "string",
                            "nullable": true
                          },
                          "code_tried": {
                            "type": "string"
                          }
                        }
                      },
                      "fee": {
                        "type": "number"
                      }
                    }
                  }
                },
                "warnings": {
                  "type": "array",
                  "description": "Daftar peringatan yang terkait dengan verifikasi telepon",
                  "items": {
                    "type": "object",
                    "properties": {
                      "feature": {
                        "type": "string",
                        "enum": [
                          "ID_VERIFICATION",
                          "NFC",
                          "LIVENESS",
                          "FACEMATCH",
                          "PROOF_OF_ADDRESS",
                          "PHONE",
                          "EMAIL",
                          "AML",
                          "LOCATION",
                          "DATABASE_VALIDATION",
                          "QUESTIONNAIRE",
                          "DOCUMENT_AI",
                          "KYB_REGISTRY",
                          "KYB_DOCUMENTS",
                          "KYB_KEY_PEOPLE",
                          "GEOLOCATION",
                          "SIGNATURE"
                        ],
                        "description": "Fitur yang menghasilkan peringatan ini. Nilai ini mengidentifikasi blok fitur tempat peringatan tersebut berada. Array peringatan setiap modul biasanya menggunakan nilai yang cocok dengan modulnya (misalnya `PHONE` di dalam `phone_verifications[].warnings`), tetapi enum di atas bersifat otoritatif di semua peringatan fitur pada payload keputusan."
                      },
                      "risk": {
                        "type": "string"
                      },
                      "additional_data": {
                        "type": "object",
                        "nullable": true
                      },
                      "log_type": {
                        "type": "string"
                      },
                      "short_description": {
                        "type": "string"
                      },
                      "long_description": {
                        "type": "string"
                      },
                      "node_id": {
                        "type": "string",
                        "description": "ID node graf alur kerja yang menghasilkan peringatan ini"
                      }
                    }
                  }
                },
                "matches": {
                  "type": "array",
                  "description": "Kecocokan yang ditemukan untuk nomor telepon ini. Setiap kecocokan memiliki `source`: `session` (sesi verifikasi lain di aplikasi Anda cocok pada nomor yang sama, dikembalikan dengan `session_id`/`session_number`/`vendor_data`/`verification_date`) atau `list_entry` (nomor berada pada daftar izin/blokir yang dikelola organisasi — lihat `/management-api/lists/overview`). Kecocokan lintas sesi menggunakan `vendor_data` yang berbeda dan dibatasi maksimal 5.",
                  "items": {
                    "type": "object",
                    "properties": {
                      "session_id": {
                        "type": "string",
                        "format": "uuid",
                        "nullable": true
                      },
                      "session_number": {
                        "type": "integer",
                        "nullable": true
                      },
                      "vendor_data": {
                        "type": "string",
                        "nullable": true
                      },
                      "verification_date": {
                        "type": "string",
                        "format": "date-time",
                        "nullable": true
                      },
                      "phone_number": {
                        "type": "string"
                      },
                      "status": {
                        "type": "string",
                        "nullable": true
                      },
                      "is_blocklisted": {
                        "type": "boolean"
                      },
                      "api_service": {
                        "type": "string",
                        "nullable": true
                      },
                      "source": {
                        "type": "string",
                        "enum": [
                          "session",
                          "list_entry"
                        ],
                        "description": "Asal kecocokan ini. `session` berarti sesi verifikasi lain di aplikasi Anda cocok dengan nilai ini. `list_entry` berarti nilai cocok dengan daftar yang dikelola organisasi (daftar izin/daftar blokir) — lihat ringkasan daftar API manajemen di `/management-api/lists/overview` untuk cara mengelola daftar tersebut."
                      }
                    }
                  }
                },
                "phone_intelligence": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/PhoneIntelligence"
                    }
                  ],
                  "description": "Sinyal intelijen telepon. Hanya ada saat add-on intelijen telepon dijalankan untuk nomor ini."
                },
                "phone_social": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/PhoneSocialFootprint"
                    }
                  ],
                  "description": "Jejak sosial dari nomor tersebut. Ada hanya jika pengaya jejak sosial dijalankan untuk nomor ini."
                }
              }
            }
          },
          "email_verifications": {
            "type": "array",
            "nullable": true,
            "description": "**Array laporan Verifikasi Email** — selalu berupa array JSON, bukan objek `email` tunggal. Bernilai `null` sampai setidaknya satu langkah email menghasilkan data. Setiap item adalah laporan lengkap, termasuk `node_id`, `status` tingkat fitur, alamat email, data kebocoran, `lifecycle[]`, `matches[]`, serta `warnings[]`.",
            "items": {
              "type": "object",
              "properties": {
                "node_id": {
                  "type": "string",
                  "description": "Pengenal unik untuk langkah email ini di dalam graf alur kerja."
                },
                "status": {
                  "type": "string",
                  "description": "Status tingkat fitur dari langkah verifikasi email ini. Tidak bergantung pada `status` sesi tingkat atas — sesi dapat mencapai keputusan keseluruhannya sementara fitur individual tetap `In Review`.",
                  "enum": [
                    "Not Finished",
                    "Approved",
                    "Declined",
                    "In Review",
                    "Expired"
                  ]
                },
                "email": {
                  "type": "string",
                  "description": "Alamat email yang sedang diverifikasi"
                },
                "is_breached": {
                  "type": "boolean",
                  "description": "Menunjukkan apakah email ditemukan dalam kebocoran data yang diketahui"
                },
                "breaches": {
                  "type": "array",
                  "description": "Daftar kebocoran data yang diketahui di mana email ini ditemukan",
                  "items": {
                    "type": "object",
                    "properties": {
                      "name": {
                        "type": "string",
                        "description": "Nama pelanggaran"
                      },
                      "domain": {
                        "type": "string",
                        "description": "Domain yang terdampak oleh kebocoran"
                      },
                      "logo_path": {
                        "type": "string",
                        "description": "URL logo layanan yang mengalami kebocoran data"
                      },
                      "breach_date": {
                        "type": "string",
                        "format": "date",
                        "description": "Tanggal saat pelanggaran terjadi"
                      },
                      "description": {
                        "type": "string",
                        "description": "Deskripsi pelanggaran"
                      },
                      "is_verified": {
                        "type": "boolean",
                        "description": "Apakah pelanggaran telah diverifikasi"
                      },
                      "data_classes": {
                        "type": "array",
                        "description": "Jenis data yang terekspos dalam pelanggaran data",
                        "items": {
                          "type": "string"
                        }
                      },
                      "breach_emails_count": {
                        "type": "integer",
                        "description": "Jumlah alamat email yang terdampak dalam kebocoran data"
                      }
                    }
                  }
                },
                "is_disposable": {
                  "type": "boolean",
                  "description": "Menunjukkan apakah email berasal dari penyedia sekali pakai"
                },
                "is_undeliverable": {
                  "type": "boolean",
                  "description": "Menunjukkan apakah alamat email tidak dapat dikirimkan"
                },
                "verification_attempts": {
                  "type": "integer",
                  "description": "Jumlah percobaan verifikasi untuk email ini"
                },
                "verified_at": {
                  "type": "string",
                  "format": "date-time",
                  "description": "Cap waktu saat email diverifikasi"
                },
                "warnings": {
                  "type": "array",
                  "description": "Daftar peringatan yang terkait dengan verifikasi email",
                  "items": {
                    "type": "object",
                    "properties": {
                      "feature": {
                        "type": "string",
                        "enum": [
                          "ID_VERIFICATION",
                          "NFC",
                          "LIVENESS",
                          "FACEMATCH",
                          "PROOF_OF_ADDRESS",
                          "PHONE",
                          "EMAIL",
                          "AML",
                          "LOCATION",
                          "DATABASE_VALIDATION",
                          "QUESTIONNAIRE",
                          "DOCUMENT_AI",
                          "KYB_REGISTRY",
                          "KYB_DOCUMENTS",
                          "KYB_KEY_PEOPLE",
                          "GEOLOCATION",
                          "SIGNATURE"
                        ],
                        "description": "Fitur yang menghasilkan peringatan ini. Nilai ini mengidentifikasi blok fitur tempat peringatan tersebut berada. Array peringatan setiap modul biasanya menggunakan nilai yang cocok dengan modulnya (misalnya `PHONE` di dalam `phone_verifications[].warnings`), tetapi enum di atas bersifat otoritatif di semua peringatan fitur pada payload keputusan."
                      },
                      "risk": {
                        "type": "string"
                      },
                      "additional_data": {
                        "type": "object",
                        "nullable": true
                      },
                      "log_type": {
                        "type": "string"
                      },
                      "short_description": {
                        "type": "string"
                      },
                      "long_description": {
                        "type": "string"
                      },
                      "node_id": {
                        "type": "string",
                        "description": "ID node graf alur kerja yang menghasilkan peringatan ini"
                      }
                    }
                  }
                },
                "lifecycle": {
                  "type": "array",
                  "description": "Daftar kronologis event dalam siklus hidup verifikasi email.",
                  "items": {
                    "type": "object",
                    "properties": {
                      "type": {
                        "type": "string"
                      },
                      "timestamp": {
                        "type": "string",
                        "format": "date-time"
                      },
                      "details": {
                        "type": "object",
                        "nullable": true,
                        "description": "Payload khusus event. Event kirim memuat `status`, `reason`; event pemeriksaan kode memuat `code_tried`, `status`; event status akhir memuat `reason` — atau `null` jika tidak ada alasan untuk dilaporkan (misalnya `EMAIL_VERIFICATION_APPROVED`).",
                        "properties": {
                          "status": {
                            "type": "string"
                          },
                          "reason": {
                            "type": "string",
                            "nullable": true
                          },
                          "code_tried": {
                            "type": "string"
                          }
                        }
                      },
                      "fee": {
                        "type": "number"
                      }
                    }
                  }
                },
                "matches": {
                  "type": "array",
                  "description": "Kecocokan yang ditemukan untuk alamat email ini. Setiap kecocokan memiliki `source`: `session` (sesi verifikasi lain di aplikasi Anda cocok pada email yang sama, dikembalikan dengan `session_id`/`session_number`/`vendor_data`/`verification_date`) atau `list_entry` (email berada pada daftar izin/blokir yang dikelola organisasi — lihat `/management-api/lists/overview`). Kecocokan lintas sesi menggunakan `vendor_data` yang berbeda dan dibatasi maksimal 5.",
                  "items": {
                    "type": "object",
                    "properties": {
                      "session_id": {
                        "type": "string",
                        "format": "uuid",
                        "nullable": true
                      },
                      "session_number": {
                        "type": "integer",
                        "nullable": true
                      },
                      "vendor_data": {
                        "type": "string",
                        "nullable": true
                      },
                      "verification_date": {
                        "type": "string",
                        "format": "date-time",
                        "nullable": true
                      },
                      "email": {
                        "type": "string",
                        "format": "email"
                      },
                      "status": {
                        "type": "string",
                        "nullable": true
                      },
                      "is_blocklisted": {
                        "type": "boolean"
                      },
                      "api_service": {
                        "type": "string",
                        "nullable": true
                      },
                      "source": {
                        "type": "string",
                        "enum": [
                          "session",
                          "list_entry"
                        ],
                        "description": "Asal kecocokan ini. `session` berarti sesi verifikasi lain di aplikasi Anda cocok dengan nilai ini. `list_entry` berarti nilai cocok dengan daftar yang dikelola organisasi (daftar izin/daftar blokir) — lihat ringkasan daftar API manajemen di `/management-api/lists/overview` untuk cara mengelola daftar tersebut."
                      }
                    }
                  }
                },
                "email_intelligence": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/EmailIntelligence"
                    }
                  ],
                  "description": "Sinyal intelijen email. Hanya ada jika add-on intelijen email dijalankan untuk alamat ini."
                },
                "email_social": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/EmailSocialFootprint"
                    }
                  ],
                  "description": "Jejak sosial dari alamat. Ada hanya jika pengaya jejak sosial dijalankan untuk alamat ini."
                }
              }
            }
          },
          "poa_verifications": {
            "type": "array",
            "nullable": true,
            "description": "**Array laporan Bukti Alamat (POA)** — selalu berupa array JSON, bukan objek `poa` tunggal. Bernilai `null` sampai setidaknya satu langkah POA menghasilkan data. Setiap item adalah laporan lengkap, termasuk `node_id`, `status` tingkat fitur, URL file dokumen, penerbit, tanggal, alamat yang diparsing, serta `warnings[]`.",
            "items": {
              "type": "object",
              "properties": {
                "node_id": {
                  "type": "string",
                  "description": "Pengenal unik untuk langkah POA ini di graf alur kerja."
                },
                "status": {
                  "type": "string",
                  "description": "Status tingkat fitur dari langkah Bukti Alamat ini. Tidak bergantung pada `status` sesi tingkat atas — sesi dapat mencapai keputusan keseluruhannya sementara fitur individual tetap `In Review`.",
                  "enum": [
                    "Not Finished",
                    "Approved",
                    "Declined",
                    "In Review",
                    "Resub Requested"
                  ]
                },
                "document_file": {
                  "type": "string",
                  "format": "uri",
                  "description": "URL dokumen bukti alamat"
                },
                "issuing_state": {
                  "type": "string",
                  "description": "Kode negara dua huruf dari negara penerbit"
                },
                "document_type": {
                  "type": "string",
                  "description": "Jenis dokumen bukti alamat"
                },
                "document_subtype": {
                  "type": "string",
                  "nullable": true,
                  "description": "Klasifikasi yang lebih spesifik dari dokumen POA dalam `document_type`-nya, jika terdeteksi. `null` jika tidak."
                },
                "document_language": {
                  "type": "string",
                  "description": "Kode bahasa dokumen"
                },
                "document_metadata": {
                  "type": "object",
                  "properties": {
                    "file_size": {
                      "type": "integer",
                      "description": "Ukuran dokumen"
                    },
                    "content_type": {
                      "type": "string",
                      "description": "Tipe konten dokumen"
                    },
                    "creation_date": {
                      "type": "string",
                      "format": "date",
                      "description": "Tanggal saat dokumen dibuat"
                    },
                    "modified_date": {
                      "type": "string",
                      "format": "date",
                      "description": "Tanggal saat dokumen dimodifikasi"
                    },
                    "overlay_manipulation": {
                      "type": "object",
                      "nullable": true,
                      "description": "Analisis forensik PDF untuk dugaan manipulasi teks overlay. Bernilai null jika tidak ditemukan bukti manipulasi overlay atau dokumen bukan berupa PDF.",
                      "properties": {
                        "detected": {
                          "type": "boolean",
                          "description": "Menentukan apakah bukti manipulasi teks overlay terdeteksi."
                        },
                        "analyzed": {
                          "type": "boolean",
                          "description": "Apakah PDF dapat dianalisis."
                        },
                        "analysis_incomplete": {
                          "type": "boolean",
                          "description": "Ada dan bernilai true hanya jika file tidak dapat diperiksa sepenuhnya. Bagian yang berhasil diperiksa tetap menampilkan temuannya jika memungkinkan, dan dokumen memunculkan peringatan penggantian teks yang belum terbukti."
                        },
                        "signals": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          },
                          "description": "Sinyal forensik yang terpicu, seperti duplicate_font_subset atau glyph_fragmentation."
                        },
                        "manipulated_regions": {
                          "type": "array",
                          "description": "Area yang diduga dimanipulasi dalam koordinat halaman PDF.",
                          "items": {
                            "type": "object",
                            "properties": {
                              "page": {
                                "type": "integer"
                              },
                              "x": {
                                "type": "number"
                              },
                              "y": {
                                "type": "number"
                              },
                              "width": {
                                "type": "number"
                              },
                              "height": {
                                "type": "number"
                              },
                              "page_width": {
                                "type": "number"
                              },
                              "page_height": {
                                "type": "number"
                              }
                            }
                          }
                        }
                      }
                    },
                    "creator": {
                      "type": "string",
                      "nullable": true,
                      "description": "Aplikasi pembuat yang tercatat dalam metadata dokumen."
                    },
                    "producer": {
                      "type": "string",
                      "nullable": true,
                      "description": "Perangkat lunak pembuat (producer) yang tercatat dalam metadata PDF."
                    },
                    "software": {
                      "type": "string",
                      "nullable": true,
                      "description": "Perangkat lunak pengeditan/pemrosesan yang tercatat dalam metadata file."
                    },
                    "encryption": {
                      "type": "string",
                      "nullable": true,
                      "description": "Skema enkripsi dokumen, jika terenkripsi."
                    },
                    "is_signed": {
                      "type": "boolean",
                      "nullable": true,
                      "description": "Apakah PDF memiliki tanda tangan digital."
                    },
                    "is_tampered": {
                      "type": "boolean",
                      "nullable": true,
                      "description": "Menentukan apakah validasi tanda tangan menunjukkan file telah dimodifikasi setelah ditandatangani."
                    },
                    "signature_info": {
                      "type": "object",
                      "nullable": true,
                      "description": "Rincian tanda tangan digital, jika ada."
                    },
                    "exif_original_date": {
                      "type": "string",
                      "nullable": true,
                      "description": "Tanggal pengambilan asli EXIF, untuk unggahan gambar."
                    },
                    "exif_digitized_date": {
                      "type": "string",
                      "nullable": true,
                      "description": "Tanggal digitalisasi EXIF, untuk unggahan gambar."
                    },
                    "processed_by_known_editor": {
                      "type": "boolean",
                      "nullable": true,
                      "description": "Apakah metadata file menunjukkan pemrosesan oleh editor dokumen yang diketahui."
                    },
                    "has_different_creation_mod_date": {
                      "type": "boolean",
                      "nullable": true,
                      "description": "Apakah tanggal pembuatan dan modifikasi berbeda — sinyal manipulasi yang umum."
                    }
                  },
                  "description": "Metadata forensik file yang diekstrak dari dokumen POA yang diunggah. Selalu berisi kunci di bawah ini (nilainya `null` jika tidak berlaku, misalnya tanggal EXIF untuk PDF). Bernilai `null` jika tidak ada metadata yang dapat diekstrak.",
                  "nullable": true
                },
                "issuer": {
                  "type": "string",
                  "description": "Nama penerbit dokumen"
                },
                "issue_date": {
                  "type": "string",
                  "format": "date",
                  "description": "Tanggal saat dokumen diterbitkan"
                },
                "expiration_date": {
                  "type": "string",
                  "format": "date",
                  "nullable": true,
                  "description": "Tanggal kedaluwarsa dokumen, jika tersedia"
                },
                "poa_address": {
                  "type": "string",
                  "description": "Alamat mentah dari dokumen bukti alamat"
                },
                "poa_formatted_address": {
                  "type": "string",
                  "description": "Alamat terformat dari dokumen bukti alamat"
                },
                "poa_parsed_address": {
                  "type": "object",
                  "properties": {
                    "address_type": {
                      "type": "string",
                      "description": "Jenis alamat (Jalan, Jalan Utama, dll.)"
                    },
                    "street_1": {
                      "type": "string",
                      "description": "Alamat jalan utama"
                    },
                    "street_2": {
                      "type": "string",
                      "nullable": true,
                      "description": "Alamat jalan sekunder"
                    },
                    "city": {
                      "type": "string",
                      "description": "Nama kota"
                    },
                    "region": {
                      "type": "string",
                      "description": "Nama wilayah atau negara bagian"
                    },
                    "country": {
                      "type": "string",
                      "description": "Kode negara dua huruf"
                    },
                    "postal_code": {
                      "type": "string",
                      "description": "Kode pos"
                    },
                    "document_location": {
                      "type": "object",
                      "properties": {
                        "latitude": {
                          "type": "number",
                          "description": "Koordinat lintang"
                        },
                        "longitude": {
                          "type": "number",
                          "description": "Koordinat bujur"
                        }
                      }
                    }
                  }
                },
                "name_on_document": {
                  "type": "string",
                  "nullable": true,
                  "description": "Nama pemegang akun / penerima yang diekstrak dari dokumen POA, digunakan untuk pencocokan nama. `null` jika tidak ada nama yang dapat diekstrak."
                },
                "name_match_score_expected_details": {
                  "type": "number",
                  "nullable": true,
                  "description": "Skor kemiripan (0-100) antara `name_on_document` dan nama yang diharapkan dan diberikan saat pembuatan sesi. `null` jika salah satu pihak tidak ada."
                },
                "name_match_score_id_verification": {
                  "type": "number",
                  "nullable": true,
                  "description": "Skor kemiripan (0-100) antara `name_on_document` dan nama yang diekstrak oleh langkah verifikasi identitas. `null` jika salah satu pihak tidak ada."
                },
                "expected_details_address": {
                  "type": "string",
                  "nullable": true,
                  "description": "Alamat mentah yang diharapkan untuk verifikasi"
                },
                "expected_details_formatted_address": {
                  "type": "string",
                  "nullable": true,
                  "description": "Alamat terformat yang diharapkan untuk verifikasi"
                },
                "expected_details_parsed_address": {
                  "type": "object",
                  "description": "Detail alamat terurai yang diharapkan untuk verifikasi"
                },
                "extra_fields": {
                  "type": "object",
                  "description": "Detail perbankan dan kontak tambahan yang diekstrak dari dokumen.",
                  "properties": {
                    "bank_account_number": {
                      "type": "string",
                      "nullable": true
                    },
                    "bank_iban": {
                      "type": "string",
                      "nullable": true
                    },
                    "bank_sort_code": {
                      "type": "string",
                      "nullable": true
                    },
                    "bank_routing_number": {
                      "type": "string",
                      "nullable": true
                    },
                    "bank_swift_bic": {
                      "type": "string",
                      "nullable": true
                    },
                    "bank_branch_name": {
                      "type": "string",
                      "nullable": true
                    },
                    "bank_branch_address": {
                      "type": "string",
                      "nullable": true
                    },
                    "document_phone_number": {
                      "type": "string",
                      "nullable": true
                    },
                    "additional_names": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                },
                "extra_files": {
                  "type": "array",
                  "items": {
                    "type": "string",
                    "format": "uri"
                  },
                  "description": "File bukti alamat tambahan"
                },
                "warnings": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "feature": {
                        "type": "string",
                        "enum": [
                          "ID_VERIFICATION",
                          "NFC",
                          "LIVENESS",
                          "FACEMATCH",
                          "PROOF_OF_ADDRESS",
                          "PHONE",
                          "EMAIL",
                          "AML",
                          "LOCATION",
                          "DATABASE_VALIDATION",
                          "QUESTIONNAIRE",
                          "DOCUMENT_AI",
                          "KYB_REGISTRY",
                          "KYB_DOCUMENTS",
                          "KYB_KEY_PEOPLE",
                          "GEOLOCATION",
                          "SIGNATURE"
                        ],
                        "description": "Fitur yang menghasilkan peringatan ini. Nilai ini mengidentifikasi blok fitur tempat peringatan tersebut berada. Array peringatan setiap modul biasanya menggunakan nilai yang cocok dengan modulnya (misalnya `PHONE` di dalam `phone_verifications[].warnings`), tetapi enum di atas bersifat otoritatif di semua peringatan fitur pada payload keputusan."
                      },
                      "risk": {
                        "type": "string"
                      },
                      "additional_data": {
                        "type": "object",
                        "nullable": true
                      },
                      "log_type": {
                        "type": "string"
                      },
                      "short_description": {
                        "type": "string"
                      },
                      "long_description": {
                        "type": "string"
                      },
                      "node_id": {
                        "type": "string",
                        "description": "ID node graf alur kerja yang menghasilkan peringatan ini"
                      }
                    }
                  }
                },
                "detected_codes": {
                  "type": "array",
                  "description": "Kode QR dan barcode yang terdeteksi di setiap halaman dokumen yang diproses. Kosong jika tidak ada yang ditemukan. Kode QR yang ditemukan namun tidak dapat didekode memiliki `parsed_payload: null`.",
                  "items": {
                    "$ref": "#/components/schemas/DocumentAIDetectedCode"
                  }
                },
                "address_validation": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/AddressValidationResult"
                    }
                  ],
                  "nullable": true,
                  "description": "Validasi Alamat dari alamat pada bukti alamat ini: apakah alamat tersebut ada dan bentuk ternormalisasinya, sebagaimana yang dibaca dari dokumen (koreksi selanjutnya terhadap `poa_address` tidak menjalankannya kembali). Hadir jika langkah Bukti Alamat ini mengaktifkan add-on Validasi Alamat dan unggahan lolos pemeriksaan dokumen; `null` jika tidak."
                }
              }
            }
          },
          "document_ai_documents": {
            "type": "array",
            "nullable": true,
            "description": "**Laporan Document AI yang dikelompokkan berdasarkan node alur kerja** — selalu berupa array JSON, tidak pernah berupa objek tunggal. Bernilai `null` sampai setidaknya satu langkah Document AI menghasilkan data. Hanya ada jika `session_kind = user`. Setiap item adalah grup node dengan `status` agregat, `node_id`, array `items[]` dari hasil per dokumen (data yang diekstraksi menggunakan kunci kolom yang dikonfigurasi), serta `warnings`.",
            "items": {
              "type": "object",
              "description": "Hasil Document AI yang dikelompokkan berdasarkan node alur kerja.",
              "properties": {
                "status": {
                  "type": "string",
                  "description": "Status Document AI agregat untuk node ini, digabungkan dari `items[]` miliknya.",
                  "enum": [
                    "Approved",
                    "Declined",
                    "In Review",
                    "Not Finished"
                  ]
                },
                "node_id": {
                  "type": "string",
                  "nullable": true,
                  "description": "Pengenal unik untuk langkah Document AI ini di graf alur kerja."
                },
                "items": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "uuid": {
                        "type": "string",
                        "format": "uuid"
                      },
                      "node_id": {
                        "type": "string",
                        "nullable": true,
                        "description": "Node graf alur kerja yang menghasilkan dokumen ini."
                      },
                      "document_key": {
                        "type": "string",
                        "description": "Kunci dari dokumen Document AI yang dikonfigurasi yang sesuai dengan file ini."
                      },
                      "original_filename": {
                        "type": "string",
                        "nullable": true,
                        "description": "Nama file seperti yang diunggah oleh pengguna."
                      },
                      "file_size": {
                        "type": "integer",
                        "nullable": true,
                        "description": "Ukuran file dalam byte."
                      },
                      "file_url": {
                        "type": "string",
                        "format": "uri",
                        "nullable": true,
                        "description": "Tautan presigned berdurasi singkat ke file yang diunggah."
                      },
                      "status": {
                        "type": "string",
                        "enum": [
                          "Approved",
                          "Declined",
                          "In Review",
                          "Not Finished"
                        ],
                        "description": "Status Document AI per dokumen."
                      },
                      "extracted_data": {
                        "type": "object",
                        "additionalProperties": true,
                        "nullable": true,
                        "description": "Nilai yang diekstrak oleh Document AI, diindeks berdasarkan `key` kolom yang dikonfigurasi. Setiap nilai berupa string, angka, atau `null`."
                      },
                      "detected_codes": {
                        "type": "array",
                        "description": "Kode QR dan barcode yang terdeteksi di setiap halaman yang diproses. Kosong jika tidak ada yang ditemukan. Kode QR yang ditemukan namun tidak dapat didekode memiliki `parsed_payload: null`.",
                        "items": {
                          "$ref": "#/components/schemas/DocumentAIDetectedCode"
                        }
                      },
                      "fields": {
                        "type": "array",
                        "description": "Kolom ekstraksi yang dikonfigurasi untuk dokumen ini.",
                        "items": {
                          "type": "object",
                          "properties": {
                            "key": {
                              "type": "string",
                              "description": "Kunci kolom stabil yang digunakan sebagai kunci dalam `extracted_data`."
                            },
                            "name": {
                              "type": "string",
                              "description": "Nama kolom yang mudah dibaca manusia."
                            },
                            "instruction": {
                              "type": "string",
                              "description": "Instruksi ekstraksi yang ditampilkan kepada model."
                            },
                            "type": {
                              "type": "string",
                              "enum": [
                                "text",
                                "number",
                                "date"
                              ],
                              "description": "Tipe nilai yang diharapkan dari kolom yang diekstraksi."
                            },
                            "required": {
                              "type": "boolean",
                              "description": "Whether this field is required."
                            }
                          }
                        }
                      },
                      "document_metadata": {
                        "type": "object",
                        "nullable": true,
                        "description": "Metadata forensik file yang diekstrak dari dokumen yang diunggah (misalnya `is_tampered`). Bernilai `null` jika tidak ada yang dapat diekstrak."
                      },
                      "cross_check_result": {
                        "type": "object",
                        "nullable": true,
                        "description": "Referensi silang dari kolom dokumen yang diekstraksi terhadap data sesi lainnya. Bernilai `null` jika tidak ada pemeriksaan silang yang dilakukan."
                      },
                      "created_at": {
                        "type": "string",
                        "format": "date-time"
                      }
                    }
                  }
                },
                "warnings": {
                  "type": "array",
                  "nullable": true,
                  "items": {
                    "type": "object"
                  },
                  "description": "Log peringatan yang dimunculkan untuk node Document AI ini."
                }
              }
            }
          },
          "questionnaire_responses": {
            "type": "array",
            "nullable": true,
            "description": "**Array laporan respons Kuesioner** — selalu berupa array JSON, bukan objek `questionnaire` tunggal. Bernilai `null` sampai setidaknya satu langkah kuesioner menghasilkan data. Setiap item adalah laporan lengkap, termasuk `node_id`, metadata kuesioner, bagian dengan elemen formulir, serta jawaban pengguna.",
            "items": {
              "type": "object",
              "properties": {
                "node_id": {
                  "type": "string",
                  "description": "Pengenal unik untuk langkah kuesioner ini di dalam graf alur kerja."
                },
                "questionnaire_id": {
                  "type": "string",
                  "description": "Pengenal unik untuk kuesioner"
                },
                "title": {
                  "type": "string",
                  "description": "Judul kuesioner"
                },
                "description": {
                  "type": "string",
                  "description": "Deskripsi kuesioner"
                },
                "languages": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  },
                  "description": "Bahasa yang didukung"
                },
                "default_language": {
                  "type": "string",
                  "description": "Bahasa default"
                },
                "is_active": {
                  "type": "boolean",
                  "description": "Apakah kuesioner aktif"
                },
                "is_simple_questionnaire": {
                  "type": "boolean",
                  "description": "Apakah kuesioner merupakan formulir linier sederhana (tanpa graf percabangan)."
                },
                "questionnaire_group_id": {
                  "type": "string",
                  "format": "uuid",
                  "nullable": true,
                  "description": "Pengidentifikasi stabil dari grup kuesioner di seluruh versi."
                },
                "version": {
                  "type": "integer",
                  "nullable": true,
                  "description": "Nomor versi kuesioner yang telah dijawab."
                },
                "published_at": {
                  "type": "string",
                  "format": "date-time",
                  "nullable": true,
                  "description": "Cap waktu saat versi kuesioner ini dipublikasikan."
                },
                "sections": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "title": {
                        "type": "string",
                        "nullable": true,
                        "description": "Judul bagian"
                      },
                      "description": {
                        "type": "string",
                        "nullable": true,
                        "description": "Deskripsi bagian"
                      },
                      "items": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "uuid": {
                              "type": "string",
                              "description": "Pengenal unik untuk item"
                            },
                            "value": {
                              "type": "string",
                              "nullable": true,
                              "description": "Pengidentifikasi node stabil dari elemen formulir ini dalam graf kuesioner."
                            },
                            "element_type": {
                              "type": "string",
                              "description": "Jenis elemen kuesioner"
                            },
                            "is_required": {
                              "type": "boolean",
                              "description": "Apakah item wajib"
                            },
                            "title": {
                              "type": "string",
                              "description": "Judul item"
                            },
                            "description": {
                              "type": "string",
                              "nullable": true,
                              "description": "Deskripsi item"
                            },
                            "placeholder": {
                              "type": "string",
                              "nullable": true,
                              "description": "Teks pengganti"
                            },
                            "choices": {
                              "type": "array",
                              "nullable": true,
                              "items": {
                                "type": "object",
                                "properties": {
                                  "label": {
                                    "type": "string"
                                  },
                                  "value": {
                                    "type": "string"
                                  },
                                  "requires_text_input": {
                                    "type": "boolean",
                                    "description": "Apakah pilihan ini memerlukan input teks tambahan",
                                    "nullable": true
                                  }
                                },
                                "required": [
                                  "label",
                                  "value"
                                ]
                              },
                              "description": "Pilihan untuk elemen menu tarik-turun atau pilihan tunggal"
                            },
                            "max_files": {
                              "type": "integer",
                              "description": "Jumlah file maksimum yang diizinkan",
                              "nullable": true
                            },
                            "answer": {
                              "type": "object",
                              "description": "Jawaban yang diberikan untuk item tersebut",
                              "properties": {
                                "value": {
                                  "type": "string",
                                  "nullable": true
                                },
                                "text": {
                                  "type": "string",
                                  "nullable": true
                                },
                                "files": {
                                  "type": "array",
                                  "items": {
                                    "type": "string"
                                  },
                                  "nullable": true
                                }
                              }
                            },
                            "required_if": {
                              "type": "object",
                              "nullable": true,
                              "description": "Aturan persyaratan kondisional, saat elemen hanya diperlukan untuk jawaban tertentu."
                            },
                            "repeatable_config": {
                              "type": "object",
                              "nullable": true,
                              "description": "Konfigurasi untuk grup elemen yang dapat berulang, jika berlaku."
                            }
                          },
                          "required": [
                            "uuid",
                            "value",
                            "element_type",
                            "is_required",
                            "title"
                          ]
                        }
                      }
                    }
                  }
                },
                "status": {
                  "type": "string",
                  "description": "Status kuesioner"
                }
              }
            }
          },
          "bank_verifications": {
            "type": "array",
            "nullable": true,
            "description": "Hasil Verifikasi Bank, satu item per langkah Verifikasi Bank, untuk Verifikasi Pengguna dan Bisnis. `null` sampai suatu langkah menghasilkannya. Kolom `method` setiap item menyebutkan bagaimana akun diverifikasi: `open_banking` (masuk ke bank) atau `account_lookup` (pemeriksaan akun), atau fallback `statement` atau `microdeposits`, dan `none` saat orang tersebut melanjutkan tanpa bank sebelum upaya apa pun dievaluasi (`continued_without_bank`). Lihat [Metode verifikasi bank](/id/core-technology/bank-verification/verification-methods).",
            "items": {
              "$ref": "#/components/schemas/BankVerificationResult"
            }
          },
          "signatures": {
            "type": "array",
            "description": "Hasil Tanda Tangan Elektronik, satu item per penandatangan dan langkah tanda tangan, untuk Verifikasi Pengguna dan Verifikasi Bisnis (KYB). Hanya ada jika alur kerja memiliki langkah Tanda Tangan Elektronik; berupa array kosong hingga penandatangan mencapainya. Lihat [Laporan Tanda Tangan Elektronik](/id/core-technology/electronic-signature/report-electronic-signature).",
            "items": {
              "$ref": "#/components/schemas/SignatureResult"
            }
          },
          "aml_screenings": {
            "type": "array",
            "nullable": true,
            "description": "**Array laporan Skrining AML** — selalu berupa array JSON, tidak pernah berupa objek tunggal `aml`. `null` hingga setidaknya satu langkah AML menghasilkan data. Setiap item merupakan laporan lengkap, termasuk `node_id`, `status` tingkat fitur, `total_hits`, `entity_type`, `hits[]`, `score`, `screened_data`, `is_ongoing_monitoring_enabled`, dan `warnings[]`.",
            "items": {
              "$ref": "#/components/schemas/AMLScreening"
            }
          },
          "ip_analyses": {
            "type": "array",
            "nullable": true,
            "description": "**Array laporan Analisis Perangkat & IP** — selalu berupa array JSON, bukan objek `ip_analysis` tunggal. Bernilai `null` sampai setidaknya satu langkah analisis IP menghasilkan data. Setiap item adalah laporan lengkap, termasuk `node_id`, `status` tingkat fitur, data IP dan geolokasi, sidik jari perangkat, serta `warnings[]`. Entri dengan `(node_id, ip_address, device_fingerprint)` duplikat akan dideduplikasi di sisi server.",
            "items": {
              "type": "object",
              "properties": {
                "node_id": {
                  "type": "string",
                  "description": "Pengenal unik untuk langkah Analisis Perangkat & IP ini di graf alur kerja."
                },
                "status": {
                  "type": "string",
                  "description": "Status tingkat fitur dari entri Analisis Perangkat & IP ini. Tidak bergantung pada `status` sesi tingkat atas — sesi dapat mencapai keputusan keseluruhannya sementara fitur individual tetap `In Review`.",
                  "enum": [
                    "Not Finished",
                    "Approved",
                    "Declined",
                    "In Review",
                    "Resub Requested"
                  ]
                },
                "device_brand": {
                  "type": "string",
                  "description": "Merek perangkat yang digunakan"
                },
                "device_model": {
                  "type": "string",
                  "description": "Model perangkat yang digunakan"
                },
                "browser_family": {
                  "type": "string",
                  "description": "Famili browser yang digunakan"
                },
                "os_family": {
                  "type": "string",
                  "description": "Keluarga sistem operasi"
                },
                "platform": {
                  "type": "string",
                  "description": "Jenis platform (mobile, desktop, dll)"
                },
                "device_fingerprint": {
                  "type": "string",
                  "nullable": true,
                  "description": "Pengenal unik sidik jari perangkat"
                },
                "ip_country": {
                  "type": "string",
                  "description": "Negara yang terdeteksi dari IP"
                },
                "ip_country_code": {
                  "type": "string",
                  "description": "Kode negara dua huruf dari IP"
                },
                "ip_state": {
                  "type": "string",
                  "description": "Negara bagian/wilayah yang terdeteksi dari IP"
                },
                "ip_city": {
                  "type": "string",
                  "description": "Kota yang terdeteksi dari IP"
                },
                "latitude": {
                  "type": "number",
                  "description": "Koordinat lintang lokasi IP"
                },
                "longitude": {
                  "type": "number",
                  "description": "Koordinat bujur dari lokasi IP"
                },
                "ip_address": {
                  "type": "string",
                  "description": "Alamat IP"
                },
                "isp": {
                  "type": "string",
                  "nullable": true,
                  "description": "Penyedia Layanan Internet"
                },
                "organization": {
                  "type": "string",
                  "nullable": true,
                  "description": "Organisasi yang terkait dengan IP"
                },
                "is_vpn_or_tor": {
                  "type": "boolean",
                  "description": "Menentukan apakah IP berasal dari VPN atau jaringan Tor"
                },
                "is_data_center": {
                  "type": "boolean",
                  "description": "Menentukan apakah IP berasal dari pusat data"
                },
                "time_zone": {
                  "type": "string",
                  "description": "Zona waktu yang terdeteksi dari IP"
                },
                "time_zone_offset": {
                  "type": "string",
                  "description": "Offset zona waktu"
                },
                "ip": {
                  "type": "object",
                  "description": "Geolokasi IP dari entri ini ditambah jarak lingkaran besar (km) ke alamat dokumen identitas dan alamat dokumen bukti alamat (POA). Jarak bernilai `null` jika salah satu pihak tidak memiliki lokasi yang dapat ditentukan.",
                  "properties": {
                    "location": {
                      "type": "object",
                      "nullable": true,
                      "properties": {
                        "latitude": {
                          "type": "number",
                          "example": 41.2706327
                        },
                        "longitude": {
                          "type": "number",
                          "example": 1.9770097
                        }
                      },
                      "description": "Koordinat, atau `null` jika tidak tersedia."
                    },
                    "distance_from_id_document": {
                      "type": "number",
                      "nullable": true,
                      "example": 23.4
                    },
                    "distance_from_poa_document": {
                      "type": "number",
                      "nullable": true,
                      "example": 12.3
                    }
                  }
                },
                "id_document": {
                  "type": "object",
                  "description": "Lokasi yang diekstrak dari alamat dokumen identitas ditambah jarak (km) ke geolokasi IP dan alamat dokumen POA. `location` bernilai `null` jika tidak ada alamat dokumen yang dapat di-geocode.",
                  "properties": {
                    "location": {
                      "type": "object",
                      "nullable": true,
                      "properties": {
                        "latitude": {
                          "type": "number",
                          "example": 41.2706327
                        },
                        "longitude": {
                          "type": "number",
                          "example": 1.9770097
                        }
                      },
                      "description": "Koordinat, atau `null` jika tidak tersedia."
                    },
                    "distance_from_ip": {
                      "type": "number",
                      "nullable": true,
                      "example": 23.4
                    },
                    "distance_from_poa_document": {
                      "type": "number",
                      "nullable": true,
                      "example": 18.7
                    }
                  }
                },
                "poa_document": {
                  "type": "object",
                  "description": "Lokasi yang diekstrak dari dokumen Bukti Alamat ditambah jarak (km) ke geolokasi IP dan alamat dokumen identitas. `location` bernilai `null` jika sesi tidak memiliki langkah POA atau alamat tidak dapat di-geocode.",
                  "properties": {
                    "location": {
                      "type": "object",
                      "nullable": true,
                      "properties": {
                        "latitude": {
                          "type": "number",
                          "example": 41.2706327
                        },
                        "longitude": {
                          "type": "number",
                          "example": 1.9770097
                        }
                      },
                      "description": "Koordinat, atau `null` jika tidak tersedia."
                    },
                    "distance_from_ip": {
                      "type": "number",
                      "nullable": true,
                      "example": 12.3
                    },
                    "distance_from_id_document": {
                      "type": "number",
                      "nullable": true,
                      "example": 18.7
                    }
                  }
                },
                "warnings": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "feature": {
                        "type": "string",
                        "enum": [
                          "ID_VERIFICATION",
                          "NFC",
                          "LIVENESS",
                          "FACEMATCH",
                          "PROOF_OF_ADDRESS",
                          "PHONE",
                          "EMAIL",
                          "AML",
                          "LOCATION",
                          "DATABASE_VALIDATION",
                          "QUESTIONNAIRE",
                          "DOCUMENT_AI",
                          "KYB_REGISTRY",
                          "KYB_DOCUMENTS",
                          "KYB_KEY_PEOPLE",
                          "GEOLOCATION",
                          "SIGNATURE"
                        ],
                        "description": "Fitur yang menghasilkan peringatan ini. Nilai ini mengidentifikasi blok fitur tempat peringatan tersebut berada. Array peringatan setiap modul biasanya menggunakan nilai yang cocok dengan modulnya (misalnya `PHONE` di dalam `phone_verifications[].warnings`), tetapi enum di atas bersifat otoritatif di semua peringatan fitur pada payload keputusan."
                      },
                      "risk": {
                        "type": "string"
                      },
                      "additional_data": {
                        "type": "object",
                        "nullable": true
                      },
                      "log_type": {
                        "type": "string"
                      },
                      "short_description": {
                        "type": "string"
                      },
                      "long_description": {
                        "type": "string"
                      },
                      "node_id": {
                        "type": "string",
                        "description": "ID node graf alur kerja yang menghasilkan peringatan ini"
                      }
                    }
                  }
                },
                "matches": {
                  "type": "array",
                  "description": "Kecocokan lintas sesi yang ditemukan untuk alamat IP atau identitas perangkat entri ini. Setiap kecocokan merupakan sesi verifikasi lain dalam aplikasi Anda (`source` selalu berupa `session`) yang memiliki nilai yang sama, selalu milik pengguna vendor / `vendor_data` yang berbeda dari sesi saat ini, dibatasi maksimal 5 per kolektor (`device_fingerprint` menjumlahkan dua kolektor yang dibatasi secara independen, sehingga memungkinkan hingga 10 entri). Setiap item memuat `match_source`, `confidence`, `match_mode`, `device_info`, dan `location_info`; kunci `recovery_similarity`, `tls_ja4_corroborated`, dan `recovery_gate_reason` hanya ada jika `match_source` bernilai `recovered_high`.",
                  "items": {
                    "type": "object",
                    "additionalProperties": false,
                    "properties": {
                      "session_id": {
                        "type": "string",
                        "format": "uuid",
                        "description": "ID sesi dari sesi yang cocok."
                      },
                      "session_number": {
                        "type": "integer",
                        "description": "Nomor urut sesi yang cocok."
                      },
                      "vendor_data": {
                        "type": "string",
                        "nullable": true,
                        "description": "`vendor_data` dari sesi yang cocok — selalu berbeda dari pengguna vendor sesi saat ini."
                      },
                      "verification_date": {
                        "type": "string",
                        "format": "date-time",
                        "nullable": true,
                        "description": "Tanggal pembuatan sesi yang cocok (`YYYY-MM-DDTHH:MM:SSZ`)."
                      },
                      "match_type": {
                        "type": "string",
                        "enum": [
                          "ip_address",
                          "device_fingerprint"
                        ],
                        "description": "Apakah kecocokan didasarkan pada alamat IP atau fingerprint perangkat"
                      },
                      "match_source": {
                        "type": "string",
                        "enum": [
                          "ip_address",
                          "persistent_id",
                          "legacy_fp",
                          "recovered_high"
                        ],
                        "description": "Bagaimana kecocokan ini tercapai: `ip_address` (alamat IP bersama — kolokasi jaringan, bukan klaim identitas perangkat), `persistent_id` (pengidentifikasi perangkat persisten yang tersimpan secara persis), `legacy_fp` (hash sidik jari perangkat lama `didit-fp-*`), atau `recovered_high` (kecocokan pemulihan sidik jari samar dengan keyakinan tinggi). Kandidat pemulihan dengan keyakinan lebih rendah hanya muncul sebagai peringatan risiko, tidak pernah dalam array ini."
                      },
                      "matched_value": {
                        "type": "string",
                        "nullable": true,
                        "description": "Nilai yang cocok: alamat IP bersama, pengidentifikasi perangkat persisten atau hash sidik jari lama, atau — untuk `recovered_high` — UUID perangkat yang dipulihkan."
                      },
                      "status": {
                        "type": "string",
                        "description": "Status siklus hidup dari sesi yang cocok."
                      },
                      "is_blocklisted": {
                        "type": "boolean",
                        "description": "Apakah nilai yang cocok ada di daftar blokir. Saat ini selalu `false` untuk kecocokan perangkat/IP."
                      },
                      "api_service": {
                        "type": "string",
                        "nullable": true,
                        "description": "Layanan API mandiri dari sesi yang cocok; `null` untuk sesi alur kerja."
                      },
                      "source": {
                        "type": "string",
                        "enum": [
                          "session"
                        ],
                        "description": "Selalu `session` untuk kecocokan perangkat/IP — setiap kecocokan adalah sesi verifikasi lain di aplikasi Anda."
                      },
                      "device_info": {
                        "type": "object",
                        "description": "Detail perangkat yang diamati pada sesi yang cocok.",
                        "properties": {
                          "device_brand": {
                            "type": "string",
                            "nullable": true
                          },
                          "device_model": {
                            "type": "string",
                            "nullable": true
                          },
                          "browser_family": {
                            "type": "string",
                            "nullable": true
                          },
                          "os_family": {
                            "type": "string",
                            "nullable": true
                          },
                          "platform": {
                            "type": "string",
                            "nullable": true
                          },
                          "device_fingerprint": {
                            "type": "string",
                            "nullable": true
                          }
                        }
                      },
                      "location_info": {
                        "type": "object",
                        "description": "Detail jaringan dan geolokasi yang diamati pada sesi yang cocok.",
                        "properties": {
                          "ip_address": {
                            "type": "string",
                            "nullable": true
                          },
                          "ip_country": {
                            "type": "string",
                            "nullable": true
                          },
                          "ip_country_code": {
                            "type": "string",
                            "nullable": true
                          },
                          "ip_state": {
                            "type": "string",
                            "nullable": true
                          },
                          "ip_city": {
                            "type": "string",
                            "nullable": true
                          },
                          "is_vpn_or_tor": {
                            "type": "boolean"
                          },
                          "is_data_center": {
                            "type": "boolean"
                          }
                        }
                      },
                      "confidence": {
                        "type": "number",
                        "minimum": 0,
                        "maximum": 1,
                        "description": "Skor keyakinan identifikasi di sisi server, dihitung sebagai `1 - P(false positive)`: `1.0` untuk kecocokan deterministik (`persistent_id`, atau `recovered_high` berbasis perangkat keras), `0.5` untuk `legacy_fp`, `0.0` untuk `ip_address` (hanya ko-lokasi), dan nilai yang disesuaikan dengan koroborasi di bawah `1.0` untuk kecocokan probabilistik yang dipulihkan (lebih tinggi jika sidik jari TLS JA4 dan negara berdasarkan alamat IP secara independen cocok)."
                      },
                      "match_mode": {
                        "type": "string",
                        "enum": [
                          "deterministic",
                          "probabilistic",
                          "co_occurrence"
                        ],
                        "description": "Kelas bukti dari kecocokan: `deterministic` (pengenal persis yang tersimpan atau berakar pada perangkat keras yang tidak dapat bertabrakan antar perangkat fisik), `probabilistic` (bukti sidik jari yang tidak persis), atau `co_occurrence` (hanya jaringan bersama, tanpa klaim identitas perangkat)."
                      },
                      "recovery_similarity": {
                        "type": "number",
                        "description": "Kemiripan kosinus dari pencocokan pemulihan sidik jari, dibulatkan hingga 4 desimal. Hanya ada jika `match_source` bernilai `recovered_high`."
                      },
                      "tls_ja4_corroborated": {
                        "type": "boolean",
                        "description": "Apakah fingerprint JA4 TLS dari kedua observasi cocok — sinyal yang diamati server yang tidak dapat dipalsukan oleh browser. Hanya ada jika `match_source` bernilai `recovered_high`."
                      },
                      "recovery_gate_reason": {
                        "type": "string",
                        "description": "Alasan mengapa pencocokan pemulihan lolos dari gerbang ketat positif palsu: `hardware_root_match` (pengidentifikasi perangkat yang berakar pada perangkat keras cocok persis) atau, pada konfigurasi yang menerima bukti probe saja, `exact_composite_plus_<n>_families` / `very_high_similarity_plus_<n>_families`. Hanya ada jika `match_source` adalah `recovered_high`."
                      }
                    }
                  }
                },
                "browser_version": {
                  "type": "string",
                  "nullable": true
                },
                "os_version": {
                  "type": "string",
                  "nullable": true
                },
                "user_agent": {
                  "type": "string",
                  "nullable": true,
                  "description": "String user agent milik browser."
                },
                "accept_language": {
                  "type": "string",
                  "nullable": true,
                  "description": "Header `Accept-Language` yang dikirimkan oleh browser."
                },
                "session_identifier": {
                  "type": "string",
                  "nullable": true,
                  "description": "Pengenal sesi penjelajahan tempat verifikasi dijalankan."
                },
                "session_age_ms": {
                  "type": "integer",
                  "nullable": true,
                  "description": "Usia sesi penjelajahan tersebut dalam milidetik saat langkah dijalankan."
                },
                "coords_accuracy": {
                  "type": "number",
                  "nullable": true,
                  "description": "Radius akurasi, dalam meter, dari koordinat yang dilaporkan perangkat."
                },
                "raw_device_data": {
                  "type": "object",
                  "nullable": true,
                  "additionalProperties": true,
                  "description": "Sinyal perangkat mentah yang dikumpulkan untuk langkah ini."
                }
              }
            }
          },
          "geolocation_checks": {
            "type": "array",
            "nullable": true,
            "description": "**Array hasil verifikasi Lokasi**, satu per langkah verifikasi Lokasi: upaya yang diterima dari langkah tersebut. Bernilai `null` sampai langkah verifikasi Lokasi menghasilkan data. Upaya-upaya sebelumnya dari langkah yang sama berada di `geolocation_attempts`.",
            "items": {
              "$ref": "#/components/schemas/GeolocationCheck"
            }
          },
          "geolocation_attempts": {
            "type": "array",
            "nullable": true,
            "description": "Setiap upaya dari setiap langkah verifikasi Lokasi pada sesi ini, yang terlama terlebih dahulu. Upaya yang digantikan oleh pengiriman ulang akan dikecualikan. Alur kerja yang menyembunyikan `geolocation_checks` melalui atribut responsnya juga akan menyembunyikan daftar ini.",
            "items": {
              "$ref": "#/components/schemas/GeolocationAttempt"
            }
          },
          "database_validations": {
            "type": "array",
            "nullable": true,
            "description": "**Array laporan Validasi Database** — selalu berupa array JSON, tidak pernah berupa objek `database_validation` tunggal. Bernilai `null` sampai setidaknya satu langkah validasi DB menghasilkan data. Setiap item merupakan laporan lengkap, termasuk `node_id`, `status` tingkat fitur, `screened_data`, `validations[]` per layanan (masing-masing dengan `source_data` registri), dan `warnings[]`. Kolom `screened_data` dan `source_data` bervariasi menurut negara:\n\n**ARG (Argentina)**: screened_data: {document_number, selfie, gender, first_name, last_name}. source_data: {identification_number, first_name, last_name, full_name, date_of_birth, date_of_death, tax_id, tax_id_type, face_match_score, sit_1_since, banks, last_position, highest_position, rejected_checks}. Menggunakan validasi pencocokan wajah biometrik RENAPER. Jenis kelamin disimpulkan secara otomatis dari analisis wajah atau nama depan jika tidak tertera pada dokumen (misalnya, SIM)\n\n**BOL (Bolivia)**: screened_data: {document_number, date_of_birth, first_name, last_name}. source_data: {identification_number, first_name, last_name, full_name, date_of_birth, gender}\n\n**BRA (Brasil)**: screened_data: {tax_number, first_name, last_name, date_of_birth}. source_data selalu menyertakan {identification_number, first_name, last_name, date_of_birth, lgpd_minor, minor_under_18, minor_under_16} untuk pencocokan CPF yang berhasil. Pencarian orang dewasa yang berhasil menetapkan penanda tersebut ke false. Layanan Consulta CPF Receita Federal dapat mengembalikan HTTP 422 (anak di bawah 18 tahun) atau 451 (di bawah 16 tahun) dengan data yang ditahan berdasarkan LGPD; dalam kasus tersebut, source_data menetapkan penanda minor ke true sebagaimana mestinya, menyertakan status HTTP dari layanan upstream, dan validasi tingkat kolom bernilai no_match. Lihat bagian Brasil pada referensi Kode Hasil Validasi Database untuk daftar kode selengkapnya.\n\n**CHL (Chili)**: screened_data: {personal_number, first_name, last_name, date_of_birth}. source_data: {identification_number, first_name, last_name, date_of_birth, gender}\n\n**COL (Kolombia)**: screened_data: {document_number, document_type, first_name, last_name}. source_data: {identification_number, first_name, last_name, full_name, date_of_birth, document_type}\n\n**CRI (Kosta Rika)**: screened_data: {personal_number, first_name, last_name}. source_data: {identification_number, first_name, last_name, full_name}\n\n**DOM (Republik Dominika)**: screened_data: {personal_number}. source_data: {identification_number} (hanya mengembalikan valid/invalid)\n\n**ECU (Ekuador)**: screened_data: {personal_number, first_name, last_name}. source_data: {identification_number, first_name, last_name, street, formatted_address, gender, nationality, education, marital_status, spouse, mother_name, father_name, profession}\n\n**ESP (Spanyol)**: screened_data: {personal_number, document_type, expiration_date, first_name, last_name}. source_data: {identification_number, first_name, last_name, full_name, document_type, expiration_date}\n\n**GTM (Guatemala)**: screened_data: {document_number, first_name, last_name}. source_data: {identification_number, first_name, last_name, full_name}\n\n**HND (Honduras)**: screened_data: {document_number, first_name, last_name}. source_data: {identification_number, first_name, last_name, full_name}\n\n**MEX (Meksiko)**: screened_data: {personal_number (CURP), first_name, last_name}. source_data: {identification_number, first_name, last_name, full_name, date_of_birth, gender, nationality, curp_status, state_of_birth, doc_probatorio, registration_year, registration_state, registration_municipality, num_acta, crip, issuing_state_code, foreign_registry_number, folio_carta, folio_certificado}. Menggunakan registri sipil RENAPO. Layanan pemeriksaan validitas INE terpisah juga tersedia untuk MEX sebagai validasi satu per satu tambahan.\n\n**PAN (Panama)**: screened_data: {personal_number, selfie}. source_data: {identification_number}. Menggunakan validasi biometrik SIB\n\n**PER (Peru)**: screened_data: {personal_number (DNI), first_name, last_name}. source_data: {identification_number, first_name, last_name, paternal_name, maternal_name, verification_number, verification_letter}\n\n**PRY (Paraguay)**: screened_data: {document_number, first_name, last_name}. source_data: {identification_number, first_name, last_name, full_name}\n\n**SLV (El Salvador)**: screened_data: {document_number, date_of_birth, first_name, last_name}. source_data: {identification_number, first_name, last_name, full_name}\n\n**URY (Uruguay)**: screened_data: {personal_number, date_of_birth, first_name, last_name}. source_data: {identification_number, first_name, last_name, full_name}\n\n**VEN (Venezuela)**: screened_data: {document_number, first_name, last_name}. source_data: {identification_number, first_name, last_name, full_name, gender, date_of_birth, document_type}",
            "items": {
              "type": "object",
              "properties": {
                "node_id": {
                  "type": "string",
                  "description": "Pengenal unik untuk langkah validasi database ini di dalam graf alur kerja."
                },
                "issuing_state": {
                  "type": "string",
                  "description": "Kode ISO 3166-1 alpha-3 dari negara yang sumber pemerintah/registrinya dikueri (misalnya `BRA`, `MEX`, `ESP`, `NGA`, `IDN`). Validasi Database mencakup 60+ negara di seluruh kawasan Amerika, Eropa, Afrika, Timur Tengah, dan Asia-Pasifik, ditambah sumber multi-negara global — cakupan terus bertambah secara berkala, jadi perlakukan nilai ini sebagai set terbuka dan bukan enum tetap."
                },
                "validation_type": {
                  "type": "string",
                  "enum": [
                    "one_by_one",
                    "two_by_two",
                    "not_enabled"
                  ],
                  "description": "Bagaimana hasil dikuatkan: `one_by_one` (hasil layanan tunggal), `two_by_two` (dua atau lebih layanan berbeda secara independen mencocokkan nomor identifikasi sepenuhnya), atau `not_enabled` (disimpan saat tidak ada layanan yang menghasilkan kecocokan yang dapat digunakan). Nilai ini tidak pernah `null`. Mode validasi 2x2 biometrik khusus saat ini tersedia untuk `ECU` dan `PER`."
                },
                "screened_data": {
                  "type": "object",
                  "description": "Data input yang digunakan untuk validasi. Kolom bervariasi menurut negara — lihat dokumentasi Validasi Database (`/core-technology/database-validation/overview`) untuk format spesifik setiap negara.",
                  "properties": {
                    "last_name": {
                      "type": "string"
                    },
                    "first_name": {
                      "type": "string"
                    },
                    "tax_number": {
                      "type": "string",
                      "description": "Brasil: CPF (11 digit)"
                    },
                    "personal_number": {
                      "type": "string",
                      "description": "Chili: RUT, DOM: Cédula (11 digit), ECU: Cédula (10 digit), ESP: DNI/NIE, MEX: CURP (18 karakter), PER: DNI (8 digit), URY: CI"
                    },
                    "document_number": {
                      "type": "string",
                      "description": "ARG: DNI, BOL: CI, COL: Cédula, GTM: DPI, HND: DNI, PAN: Cédula, PRY: CI, SLV: DUI, VEN: Cédula"
                    },
                    "date_of_birth": {
                      "type": "string",
                      "format": "date"
                    },
                    "document_type": {
                      "type": "string",
                      "description": "COL: CC/CE/TI/NIT, ESP: ID/PASSPORT"
                    },
                    "expiration_date": {
                      "type": "string",
                      "format": "date",
                      "description": "Wajib untuk ESP"
                    }
                  }
                },
                "validations": {
                  "type": "array",
                  "description": "Satu entri per layanan registri yang mengembalikan payload validasi. Setiap entri mengidentifikasi layanan (`service_id`, `service_name`) dan memuat perbandingan `validation` per kolom, `outcome_code` / `outcome_detail` layanan jika dilaporkan, serta catatan registri yang dinormalisasi dalam `source_data`.",
                  "items": {
                    "type": "object",
                    "properties": {
                      "service_id": {
                        "type": "string",
                        "description": "Pengenal layanan registri yang menghasilkan hasil validasi ini.",
                        "example": "bra_cpf"
                      },
                      "service_name": {
                        "type": "string",
                        "description": "Nama layanan registri yang mudah dibaca manusia.",
                        "example": "Brazil - CPF status check"
                      },
                      "validation": {
                        "type": "object",
                        "description": "Hasil dari validasi kolom.",
                        "properties": {
                          "full_name": {
                            "type": "string",
                            "description": "Hasil pencocokan untuk nama lengkap (misalnya, 'full_match', 'partial_match', 'no_match')."
                          },
                          "date_of_birth": {
                            "type": "string",
                            "description": "Hasil pencocokan untuk tanggal lahir."
                          },
                          "identification_number": {
                            "type": "string",
                            "description": "Hasil pencocokan untuk nomor identifikasi."
                          }
                        }
                      },
                      "outcome_code": {
                        "type": "string",
                        "nullable": true,
                        "description": "Hasil pencarian registri yang dapat dibaca mesin (misalnya `MATCH`, `NO_MATCH`, `PARTIAL_MATCH`, `INCONCLUSIVE`, kode spesifik sumber). Ada jika layanan melaporkannya."
                      },
                      "outcome_detail": {
                        "type": "string",
                        "nullable": true,
                        "description": "Penjelasan `outcome_code` yang mudah dibaca manusia, jika disediakan oleh layanan."
                      },
                      "source_data": {
                        "type": "object",
                        "description": "Data yang dikembalikan dari database pemerintah. Kolom umum: identification_number, first_name, last_name, full_name, date_of_birth, gender. Kolom tambahan berdasarkan negara: BRA selalu menyertakan lgpd_minor, minor_under_18, dan minor_under_16 pada pencocokan CPF yang berhasil; ini juga menyertakan status HTTP dari upstream ketika data CPF ditahan berdasarkan LGPD (HTTP 422/451). ECU menambahkan street, formatted_address, nationality, education, marital_status, spouse, mother_name, father_name, profession. PER menambahkan paternal_name, maternal_name, verification_number, verification_letter. ESP menambahkan document_type, expiration_date. VEN/COL menambahkan document_type.",
                        "additionalProperties": true
                      }
                    }
                  }
                },
                "errors": {
                  "type": "array",
                  "description": "Kesalahan yang dikembalikan oleh layanan registri saat memvalidasi, masing-masing ditandai dengan `service_id` yang menghasilkannya. **Kunci ini tidak disertakan sama sekali jika tidak ada kesalahan.**",
                  "items": {
                    "type": "object",
                    "description": "Objek error dari layanan upstream yang disertakan apa adanya — kuncinya bervariasi menurut layanan (biasanya pesan/kode dan detail spesifik penyedia apa pun) — ditambah `service_id` yang mengidentifikasi layanan yang mengalami error.",
                    "properties": {
                      "service_id": {
                        "type": "string",
                        "nullable": true,
                        "description": "Pengenal layanan registri yang mengalami eror."
                      }
                    },
                    "additionalProperties": true
                  }
                },
                "match_type": {
                  "type": "string",
                  "enum": [
                    "no_match",
                    "partial_match",
                    "full_match"
                  ],
                  "nullable": true,
                  "description": "Hasil kecocokan agregat di seluruh layanan yang dipanggil. `null` hingga validasi telah dievaluasi."
                },
                "status": {
                  "type": "string",
                  "description": "Status tingkat fitur dari validasi database ini. Tidak bergantung pada `status` sesi tingkat atas — sesi dapat mencapai keputusan keseluruhannya sementara fitur individual tetap `In Review`.",
                  "enum": [
                    "Not Finished",
                    "Approved",
                    "Declined",
                    "In Review",
                    "Resub Requested"
                  ]
                },
                "warnings": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "feature": {
                        "type": "string",
                        "enum": [
                          "ID_VERIFICATION",
                          "NFC",
                          "LIVENESS",
                          "FACEMATCH",
                          "PROOF_OF_ADDRESS",
                          "PHONE",
                          "EMAIL",
                          "AML",
                          "LOCATION",
                          "DATABASE_VALIDATION",
                          "QUESTIONNAIRE",
                          "DOCUMENT_AI",
                          "KYB_REGISTRY",
                          "KYB_DOCUMENTS",
                          "KYB_KEY_PEOPLE",
                          "GEOLOCATION",
                          "SIGNATURE"
                        ],
                        "description": "Fitur yang menghasilkan peringatan ini. Nilai ini mengidentifikasi blok fitur tempat peringatan tersebut berada. Array peringatan setiap modul biasanya menggunakan nilai yang cocok dengan modulnya (misalnya `PHONE` di dalam `phone_verifications[].warnings`), tetapi enum di atas bersifat otoritatif di semua peringatan fitur pada payload keputusan."
                      },
                      "risk": {
                        "type": "string"
                      },
                      "additional_data": {
                        "type": "object",
                        "nullable": true
                      },
                      "log_type": {
                        "type": "string"
                      },
                      "short_description": {
                        "type": "string"
                      },
                      "long_description": {
                        "type": "string"
                      },
                      "node_id": {
                        "type": "string",
                        "description": "ID node graf alur kerja yang menghasilkan peringatan ini"
                      }
                    }
                  },
                  "description": "Peringatan yang terkait dengan validasi database."
                }
              }
            }
          },
          "database_validation_not_performed_reason": {
            "type": "object",
            "nullable": true,
            "additionalProperties": true,
            "description": "Alasan validasi database yang dikonfigurasi tidak menghasilkan output apa pun, sebagai `{code, message}` beserta kolom konteks. Hanya ada jika `database_validations` bernilai `null` untuk alur kerja yang memiliki langkah tersebut, sehingga Anda dapat membedakan antara \"registri menyetujui\" dan \"tidak ada yang berjalan\". `null` untuk kondisi lainnya.",
            "properties": {
              "code": {
                "type": "string",
                "description": "Alasan stabil yang dapat dibaca mesin."
              },
              "message": {
                "type": "string",
                "description": "Penjelasan yang mudah dibaca manusia."
              }
            }
          },
          "reviews": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "user": {
                  "type": "string",
                  "description": "Pihak yang melakukan peninjauan. Biasanya pengenal peninjau konsol (email mereka), tetapi nilainya adalah `\"API Client\"` untuk pembaruan status yang dibuat dengan kunci API dan `\"Unknown\"` jika tidak ada aktor yang dapat diidentifikasi — jadi jangan mengurai kolom ini sebagai alamat email."
                },
                "new_status": {
                  "type": "string"
                },
                "comment": {
                  "type": "string"
                },
                "created_at": {
                  "type": "string",
                  "format": "date-time"
                }
              }
            }
          },
          "assignee": {
            "type": "object",
            "nullable": true,
            "description": "Peninjau Console yang ditugaskan ke sesi, atau `null` jika tidak ada yang memegangnya.",
            "properties": {
              "email": {
                "type": "string",
                "format": "email"
              },
              "assigned_at": {
                "type": "string",
                "format": "date-time",
                "nullable": true
              }
            }
          },
          "waiting_since": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Waktu sesi mulai menunggu peninjauan. `null` kecuali sesi berstatus `In Review` dan aplikasi Anda menetapkan tenggat peninjauan."
          },
          "sla_due_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Waktu jatuh tempo peninjauan. `null` kecuali sesi berstatus `In Review` dan aplikasi Anda menetapkan tenggat peninjauan."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "Cap waktu saat sesi dibuat (ISO 8601, UTC)."
          },
          "expires_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Cap waktu saat sesi ini dijadwalkan kedaluwarsa. Diatur pada sesi Verifikasi Pengguna (KYC) saat kedaluwarsa dikonfigurasikan pada waktu pembuatan (atau setelah status `Approved` memicu penghitungan kedaluwarsa KYC). Bernilai `null` untuk sesi tanpa konfigurasi kedaluwarsa, dan untuk jenis yang tidak menggunakan kedaluwarsa (misalnya sesi Verifikasi Bisnis (KYB) yang tidak pernah menerima `expires_at`)."
          },
          "registry_checks": {
            "type": "array",
            "nullable": true,
            "description": "Pemeriksaan registri perusahaan. Hanya ada jika `session_kind = business`. Setiap item membungkus seluruh payload registri perusahaan.",
            "items": {
              "type": "object",
              "description": "Satu pemeriksaan registri perusahaan — payload registri perusahaan lengkap yang diperkaya dengan struktur kepemilikan dan peringatan. Hanya ada jika `session_kind = business`.",
              "properties": {
                "status": {
                  "type": "string",
                  "description": "Status siklus hidup fitur."
                },
                "node_id": {
                  "type": "string",
                  "nullable": true
                },
                "data_resolved": {
                  "type": "boolean"
                },
                "company": {
                  "type": "object",
                  "description": "Payload registri lengkap untuk perusahaan (catatan registri yang digabungkan dengan data apa pun yang disediakan pengguna atau diedit di konsol).",
                  "properties": {
                    "uuid": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "node_id": {
                      "type": "string",
                      "nullable": true
                    },
                    "status": {
                      "type": "string"
                    },
                    "registry_status": {
                      "type": "string",
                      "nullable": true
                    },
                    "data_resolved": {
                      "type": "boolean"
                    },
                    "company_name": {
                      "type": "string"
                    },
                    "registration_number": {
                      "type": "string",
                      "nullable": true
                    },
                    "country_code": {
                      "type": "string",
                      "description": "Negara pendirian (ISO 3166-1 alpha-2, misalnya `GB`, `DE`, `US`)."
                    },
                    "region": {
                      "type": "string",
                      "nullable": true,
                      "description": "Kode subdivisi ISO 3166-2 jika berlaku (misalnya `CA`, `NY` untuk negara bagian AS)."
                    },
                    "company_type": {
                      "type": "string",
                      "nullable": true
                    },
                    "incorporation_date": {
                      "type": "string",
                      "format": "date",
                      "nullable": true
                    },
                    "registered_address": {
                      "type": "string",
                      "nullable": true
                    },
                    "tax_number": {
                      "type": "string",
                      "nullable": true
                    },
                    "risk_level": {
                      "type": "string",
                      "enum": [
                        "LOW",
                        "MEDIUM",
                        "HIGH"
                      ],
                      "nullable": true
                    },
                    "verification_status": {
                      "type": "string",
                      "nullable": true
                    },
                    "is_from_registry": {
                      "type": "boolean"
                    },
                    "fetch_status": {
                      "type": "string",
                      "nullable": true
                    },
                    "alternative_names": {
                      "type": "string",
                      "nullable": true,
                      "description": "Nama perusahaan alternatif, nama dagang, nama terdahulu, atau nama dalam bahasa asli sebagai teks, jika dilaporkan."
                    },
                    "nature_of_business": {
                      "type": "string",
                      "nullable": true
                    },
                    "registered_capital": {
                      "type": "string",
                      "nullable": true
                    },
                    "registered_capital_amount": {
                      "type": "string",
                      "format": "decimal",
                      "nullable": true,
                      "description": "Jumlah modal terdaftar/saham sebagai string desimal (misalnya `\"100.00\"`), yang diurai dari pengajuan registri. `null` jika tidak tersedia."
                    },
                    "registered_capital_currency": {
                      "type": "string",
                      "nullable": true,
                      "description": "Kode mata uang ISO 4217 dari `registered_capital_amount` (misalnya `\"GBP\"`). `null` jika tidak tersedia."
                    },
                    "website": {
                      "type": "string",
                      "nullable": true
                    },
                    "email": {
                      "type": "string",
                      "format": "email",
                      "nullable": true
                    },
                    "phone": {
                      "type": "string",
                      "nullable": true
                    },
                    "legal_entity_identifier": {
                      "type": "string",
                      "nullable": true
                    },
                    "location_of_registration": {
                      "type": "string",
                      "nullable": true
                    },
                    "vat_number": {
                      "type": "string",
                      "nullable": true,
                      "description": "Nomor PPN Uni Eropa, saat dikumpulkan selama langkah registri yang di-hosting atau diedit sesudahnya."
                    },
                    "vat_validation_status": {
                      "type": "string",
                      "enum": [
                        "valid",
                        "invalid",
                        "format_valid",
                        "invalid_format",
                        "could_not_validate",
                        "not_applicable"
                      ],
                      "description": "Hasil validasi nomor PPN atau, jika tidak ada, `tax_number`, saat pengiriman ke registri. `valid` / `invalid`: ditentukan oleh registri resmi negara (EU VIES, Norwegia, Swiss, Brasil, Kolombia, Kosta Rika, Ekuador, Paraguay; Polandia juga melalui registri PPN domestiknya). `format_valid` / `invalid_format`: ditentukan oleh aturan format dan digit centang negara tersebut jika tidak ada registri yang dapat dikueri. `could_not_validate`: registri tidak tersedia. `not_applicable`: tidak ada nomor, negara tanpa registri atau aturan, atau sesi sandbox."
                    },
                    "vat_validated_number": {
                      "type": "string",
                      "nullable": true,
                      "description": "Nomor yang diperiksa, sebagaimana diketahui oleh sumber (misalnya nomor PPN yang diperoleh dari SIREN Prancis atau RSIN Belanda). `null` jika tidak ada pemeriksaan yang dijalankan."
                    },
                    "vat_validation_source": {
                      "type": "string",
                      "nullable": true,
                      "enum": [
                        "eu_vies",
                        "pl_vat_white_list",
                        "no_brreg",
                        "ch_uid_register",
                        "br_receita_federal",
                        "co_rues",
                        "cr_hacienda",
                        "ec_sri",
                        "py_dnit",
                        "format_rules",
                        null
                      ],
                      "description": "Sumber yang menentukan `vat_validation_status`: registri resmi, atau `format_rules`. `null` jika tidak ada pemeriksaan yang dijalankan."
                    },
                    "vat_validated_name": {
                      "type": "string",
                      "nullable": true,
                      "description": "Nama yang terdaftar pada sumber yang memvalidasi nomor tersebut, jika menyediakannya. Hanya ditetapkan saat statusnya `valid`."
                    },
                    "vat_validated_address": {
                      "type": "string",
                      "nullable": true,
                      "description": "Alamat yang terdaftar pada sumber yang memvalidasi nomor tersebut, jika sumber mengungkapkannya. Hanya diisi jika statusnya `valid`."
                    },
                    "vat_checked_at": {
                      "type": "string",
                      "format": "date-time",
                      "nullable": true,
                      "description": "Cap waktu pemeriksaan. `null` jika tidak ada pemeriksaan yang dilakukan."
                    },
                    "financial_summary": {
                      "type": "object",
                      "nullable": true
                    },
                    "officers": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "uuid": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "name": {
                            "type": "string"
                          },
                          "designation": {
                            "type": "string",
                            "nullable": true
                          },
                          "role": {
                            "type": "string",
                            "nullable": true
                          },
                          "nationality": {
                            "type": "string",
                            "nullable": true
                          },
                          "is_active": {
                            "type": "boolean"
                          },
                          "kyc_status": {
                            "type": "string",
                            "enum": [
                              "Approved",
                              "Declined",
                              "Pending"
                            ],
                            "nullable": true
                          },
                          "kyc_session_url": {
                            "type": "string",
                            "format": "uri",
                            "nullable": true
                          },
                          "first_name": {
                            "type": "string",
                            "nullable": true,
                            "description": "Nama depan ketika dilaporkan secara eksplisit oleh registri; tidak disimpulkan dari nama lengkap."
                          },
                          "last_name": {
                            "type": "string",
                            "nullable": true,
                            "description": "Nama keluarga ketika dilaporkan secara eksplisit oleh registri."
                          },
                          "address": {
                            "type": "string",
                            "nullable": true,
                            "description": "Alamat pejabat yang dilaporkan oleh registri."
                          },
                          "appointment_date": {
                            "type": "string",
                            "nullable": true,
                            "description": "Tanggal petugas diangkat.",
                            "format": "date"
                          },
                          "termination_date": {
                            "type": "string",
                            "nullable": true,
                            "description": "Tanggal pengangkatan berakhir, jika dilaporkan.",
                            "format": "date"
                          },
                          "date_of_birth": {
                            "type": "string",
                            "nullable": true,
                            "description": "Tanggal lahir lengkap yang dilaporkan registri. Bernilai null jika hanya tahun atau bulan lahir yang diketahui.",
                            "format": "date"
                          },
                          "date_of_birth_year": {
                            "type": "integer",
                            "nullable": true,
                            "minimum": 1,
                            "maximum": 9999,
                            "description": "Tahun lahir yang dilaporkan registri, termasuk saat tanggal lengkap tidak tersedia."
                          },
                          "date_of_birth_month": {
                            "type": "integer",
                            "nullable": true,
                            "minimum": 1,
                            "maximum": 12,
                            "description": "Bulan lahir yang dilaporkan registri. Null jika hanya tahun yang diketahui."
                          }
                        }
                      }
                    },
                    "beneficial_owners": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "uuid": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "name": {
                            "type": "string"
                          },
                          "first_name": {
                            "type": "string",
                            "nullable": true
                          },
                          "last_name": {
                            "type": "string",
                            "nullable": true
                          },
                          "entity_type": {
                            "type": "string",
                            "enum": [
                              "person",
                              "company"
                            ]
                          },
                          "roles": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          },
                          "ownership_min_shares": {
                            "type": "string",
                            "nullable": true,
                            "description": "Batas bawah persentase kepemilikan sebagaimana dilaporkan oleh registri. String format bebas (misalnya `\"25.00\"`, `\"50\"`); gunakan `effective_ownership_percent` untuk nilai numerik yang telah di-parse."
                          },
                          "ownership_max_shares": {
                            "type": "string",
                            "nullable": true,
                            "description": "Batas atas persentase kepemilikan sebagaimana dilaporkan oleh registri. String bentuk bebas; gunakan `effective_ownership_percent` untuk nilai numerik yang diurai."
                          },
                          "is_active": {
                            "type": "boolean"
                          },
                          "kyc_status": {
                            "type": "string",
                            "enum": [
                              "Approved",
                              "Declined",
                              "Pending"
                            ],
                            "nullable": true
                          },
                          "kyc_session_url": {
                            "type": "string",
                            "format": "uri",
                            "nullable": true
                          },
                          "effective_ownership_percent": {
                            "type": "number",
                            "nullable": true
                          },
                          "company_name": {
                            "type": "string",
                            "nullable": true
                          },
                          "registration_number": {
                            "type": "string",
                            "nullable": true
                          },
                          "country_of_birth": {
                            "type": "string",
                            "nullable": true
                          },
                          "email": {
                            "type": "string",
                            "nullable": true
                          },
                          "nationality": {
                            "type": "string",
                            "nullable": true
                          },
                          "designation": {
                            "type": "string",
                            "nullable": true
                          },
                          "voting_min_shares": {
                            "type": "string",
                            "nullable": true
                          },
                          "voting_max_shares": {
                            "type": "string",
                            "nullable": true
                          },
                          "date_of_birth": {
                            "type": "string",
                            "nullable": true,
                            "description": "Tanggal lahir lengkap jika dilaporkan.",
                            "format": "date"
                          },
                          "appointment_date": {
                            "type": "string",
                            "nullable": true,
                            "description": "Tanggal penunjukan saat dilaporkan.",
                            "format": "date"
                          },
                          "shareholding": {
                            "$ref": "#/components/schemas/KYBRegistryShareholding"
                          }
                        }
                      }
                    },
                    "addresses": {
                      "type": "array",
                      "nullable": true,
                      "description": "Setiap alamat yang dinyatakan oleh registri, satu bentuk kanonikal. Null jika tidak ada yang dinyatakan.",
                      "items": {
                        "$ref": "#/components/schemas/KYBRegistryAddress"
                      }
                    },
                    "industries": {
                      "type": "array",
                      "nullable": true,
                      "description": "Aktivitas yang diklasifikasikan oleh registri untuk perusahaan, dalam satu format kanonis. Bernilai null jika tidak ada yang dinyatakan.",
                      "items": {
                        "$ref": "#/components/schemas/KYBRegistryIndustry"
                      }
                    },
                    "accounts": {
                      "type": "object",
                      "nullable": true,
                      "additionalProperties": true,
                      "description": "Tanggal pengajuan registri, jika tersedia. Laporan tahunan dan rapat umum menggunakan last_annual_return_date dan last_agm_date; keduanya berbeda dari laporan keuangan."
                    },
                    "registry_data": {
                      "$ref": "#/components/schemas/KYBRegistryData"
                    },
                    "user_provided_data": {
                      "type": "object",
                      "description": "Data yang dikonfirmasi atau diedit oleh pengguna akhir."
                    },
                    "confirmed_by_user_at": {
                      "type": "string",
                      "format": "date-time",
                      "nullable": true
                    },
                    "last_console_edit_at": {
                      "type": "string",
                      "format": "date-time",
                      "nullable": true
                    },
                    "is_editable": {
                      "type": "boolean"
                    },
                    "ownership": {
                      "$ref": "#/components/schemas/KYBRegistryOwnership"
                    },
                    "registry_tier": {
                      "type": "string",
                      "nullable": true,
                      "description": "Tingkat registri yang dipesan oleh alur kerja: `basic`, `shareholders`, atau `ubo`. Juga terdapat di `ownership.tier_requested`."
                    },
                    "registry_tier_delivered": {
                      "type": "string",
                      "nullable": true,
                      "description": "Tingkat yang dikirimkan oleh registri dan yang ditagihkan. Juga ada di `ownership.tier_delivered`."
                    },
                    "registry_ownership_status": {
                      "type": "string",
                      "nullable": true,
                      "description": "`not_requested`, `pending`, `delivered`, `not_held`, atau `unavailable`. Juga ada di `ownership.status`."
                    },
                    "registry_monitoring": {
                      "type": "object",
                      "nullable": true,
                      "description": "Pemantau registri terbaru untuk perusahaan, atau `null` jika tidak ada.",
                      "properties": {
                        "uuid": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "status": {
                          "type": "string"
                        },
                        "unavailable_reason": {
                          "type": "string",
                          "nullable": true
                        },
                        "enrolled_at": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true
                        },
                        "cancelled_at": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true
                        },
                        "last_bill_date": {
                          "type": "string",
                          "format": "date",
                          "nullable": true
                        },
                        "next_bill_date": {
                          "type": "string",
                          "format": "date",
                          "nullable": true
                        },
                        "last_event_at": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true
                        },
                        "events_count": {
                          "type": "integer"
                        },
                        "watched_fields": {
                          "description": "Kolom perusahaan yang dipantau oleh pemantau."
                        }
                      }
                    }
                  }
                },
                "ownership_structure": {
                  "$ref": "#/components/schemas/KYBOwnershipStructure"
                },
                "warnings": {
                  "type": "array",
                  "items": {
                    "type": "object"
                  }
                }
              }
            }
          },
          "key_people_checks": {
            "type": "array",
            "nullable": true,
            "description": "Pemeriksaan pihak kunci agregat. Hanya ada jika `session_kind = business`. Setiap item menggunakan format dua wadah (`registry`, `submitted`, `ubo_kyc_summary`).",
            "items": {
              "type": "object",
              "description": "Pemeriksaan agregat terhadap pejabat perusahaan + UBO. Menggunakan format `registry` / `submitted`. Hanya ada jika session_kind = business.",
              "properties": {
                "status": {
                  "type": "string"
                },
                "node_id": {
                  "type": "string",
                  "nullable": true
                },
                "registry": {
                  "type": "object",
                  "description": "Pihak yang ditemukan melalui pemeriksaan registri.",
                  "properties": {
                    "officers": {
                      "type": "array",
                      "description": "Pejabat yang ditemukan melalui pemeriksaan registri, masing-masing diperkaya dengan status dari setiap sesi KYC turunan dan skrining AML yang dibuat untuk mereka.",
                      "items": {
                        "type": "object",
                        "properties": {
                          "uuid": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "name": {
                            "type": "string",
                            "description": "Nama lengkap pejabat sebagaimana tercatat dalam registri."
                          },
                          "designation": {
                            "type": "string",
                            "nullable": true,
                            "description": "Jabatan berupa teks bebas dari registri (misalnya `Director`, `Company Secretary`)."
                          },
                          "role": {
                            "type": "string",
                            "enum": [
                              "director",
                              "non_executive_director",
                              "secretary",
                              "chairman",
                              "ubo",
                              "shareholder",
                              "representative",
                              "founder",
                              "legal_advisor",
                              "authorized_signatory",
                              "trustee",
                              "beneficiary",
                              "settlor",
                              "protector",
                              "company_officer",
                              "investor",
                              "other"
                            ],
                            "description": "Peran pejabat yang dinormalisasi."
                          },
                          "nationality": {
                            "type": "string",
                            "nullable": true
                          },
                          "appointment_date": {
                            "type": "string",
                            "nullable": true,
                            "description": "Tanggal petugas diangkat.",
                            "format": "date"
                          },
                          "termination_date": {
                            "type": "string",
                            "nullable": true,
                            "description": "Tanggal pengangkatan berakhir, jika dilaporkan.",
                            "format": "date"
                          },
                          "is_active": {
                            "type": "boolean"
                          },
                          "address": {
                            "type": "string",
                            "nullable": true,
                            "description": "Alamat pejabat yang dilaporkan oleh registri."
                          },
                          "aml_status": {
                            "type": "string",
                            "enum": [
                              "Not Finished",
                              "Approved",
                              "Declined",
                              "In Review",
                              "Resub Requested"
                            ],
                            "nullable": true,
                            "description": "Status Skrining AML yang dijalankan untuk pejabat ini. `null` jika tidak ada Skrining AML yang dijalankan."
                          },
                          "kyc_status": {
                            "type": "string",
                            "enum": [
                              "Not Started",
                              "In Progress",
                              "Approved",
                              "Declined",
                              "In Review",
                              "Expired",
                              "Abandoned",
                              "Kyc Expired",
                              "Resubmitted",
                              "Awaiting User"
                            ],
                            "nullable": true,
                            "description": "Status siklus hidup mentah dari sesi KYC turunan yang dibuat untuk pejabat ini. Ini adalah enum status sesi lengkap (bukan set ringkas Disetujui/Ditolak/Tertunda). Bernilai `null` jika tidak ada sesi KYC turunan."
                          },
                          "kyc_session_url": {
                            "type": "string",
                            "format": "uri",
                            "nullable": true,
                            "description": "URL yang dapat dibagikan untuk sesi KYC turunan. `null` jika tidak ada sesi turunan."
                          },
                          "kyc_session_id": {
                            "type": "string",
                            "format": "uuid",
                            "nullable": true,
                            "description": "ID sesi dari sesi KYC turunan. Teruskan ke endpoint keputusan yang sama ini untuk mengambil laporan KYC lengkap orang tersebut. Bernilai `null` jika tidak ada sesi turunan."
                          },
                          "verification_workflow_type": {
                            "type": "string",
                            "nullable": true,
                            "description": "Tipe alur kerja dasar dari alur kerja sesi anak (misalnya `kyc`). `null` untuk alur kerja berbasis graf atau saat tidak ada sesi anak."
                          },
                          "verification_workflow_id": {
                            "type": "string",
                            "format": "uuid",
                            "nullable": true,
                            "description": "ID alur kerja yang digunakan oleh sesi anak. Bernilai `null` jika tidak ada sesi anak."
                          },
                          "verification_workflow_label": {
                            "type": "string",
                            "nullable": true,
                            "description": "Label alur kerja sesi turunan yang mudah dibaca manusia. `null` jika tidak diatur."
                          },
                          "verification_workflow_features": {
                            "type": "array",
                            "nullable": true,
                            "description": "Kemajuan per fitur dari sesi verifikasi anak, misalnya `[{\"feature\": \"ID_VERIFICATION\", \"status\": \"Approved\"}]`. `null` ketika sesi anak tidak memiliki daftar fitur yang dapat ditentukan.",
                            "items": {
                              "type": "object",
                              "properties": {
                                "feature": {
                                  "type": "string",
                                  "description": "Nama tampilan fitur (misalnya `ID_VERIFICATION`, `LIVENESS`, `AML`)."
                                },
                                "status": {
                                  "type": "string",
                                  "enum": [
                                    "Not Finished",
                                    "Approved",
                                    "Declined",
                                    "In Review",
                                    "Resub Requested"
                                  ],
                                  "description": "Status tingkat fitur di dalam sesi turunan."
                                }
                              }
                            }
                          },
                          "didit_internal_id": {
                            "type": "string",
                            "nullable": true,
                            "description": "Pengidentifikasi internal stabil dari individu terverifikasi di balik sesi anak — berguna untuk penautan lintas sesi. `null` jika tidak ada sesi anak atau pengguna belum diidentifikasi."
                          },
                          "kyc_document_type": {
                            "type": "string",
                            "nullable": true,
                            "description": "Jenis dokumen yang ditunjukkan dalam sesi KYC turunan (misalnya `P`, `ID`, `DL`). `null` hingga sesi turunan memiliki hasil verifikasi identitas."
                          },
                          "kyc_nationality": {
                            "type": "string",
                            "nullable": true,
                            "description": "Kewarganegaraan diekstraksi dari dokumen dalam sesi KYC anak. `null` hingga tersedia."
                          },
                          "kyc_liveness_passed": {
                            "type": "boolean",
                            "nullable": true,
                            "description": "Apakah pemeriksaan liveness sesi KYC anak berhasil. `null` jika tidak ada pemeriksaan liveness yang dijalankan."
                          },
                          "kyc_verified_at": {
                            "type": "string",
                            "format": "date-time",
                            "nullable": true,
                            "description": "Waktu ketika sesi KYC turunan mencapai `Approved`. `null` selama sesi turunan memiliki status lain."
                          },
                          "kyc_aml_categories": {
                            "type": "object",
                            "nullable": true,
                            "description": "Ringkasan per kategori yang diperoleh dari hit AML orang tersebut. `null` jika tidak ada hit.",
                            "properties": {
                              "sanctions": {
                                "type": "string",
                                "enum": [
                                  "match",
                                  "clear"
                                ]
                              },
                              "pep": {
                                "type": "string",
                                "enum": [
                                  "match",
                                  "clear"
                                ]
                              },
                              "adverse_media": {
                                "type": "string",
                                "enum": [
                                  "match",
                                  "clear"
                                ]
                              },
                              "warnings": {
                                "type": "string",
                                "enum": [
                                  "match",
                                  "clear"
                                ]
                              }
                            }
                          },
                          "kyc_notification_sent_at": {
                            "type": "string",
                            "nullable": true,
                            "description": "Stempel waktu ISO 8601 dari notifikasi undangan verifikasi terakhir yang dikirim untuk sesi turunan orang ini. `null` jika tidak ada yang dikirim."
                          },
                          "first_name": {
                            "type": "string",
                            "nullable": true,
                            "description": "Nama depan ketika dilaporkan secara eksplisit oleh registri; tidak disimpulkan dari nama lengkap."
                          },
                          "last_name": {
                            "type": "string",
                            "nullable": true,
                            "description": "Nama keluarga ketika dilaporkan secara eksplisit oleh registri."
                          },
                          "date_of_birth": {
                            "type": "string",
                            "nullable": true,
                            "description": "Tanggal lahir lengkap yang dilaporkan registri. Bernilai null jika hanya tahun atau bulan lahir yang diketahui.",
                            "format": "date"
                          },
                          "date_of_birth_year": {
                            "type": "integer",
                            "nullable": true,
                            "minimum": 1,
                            "maximum": 9999,
                            "description": "Tahun lahir yang dilaporkan registri, termasuk saat tanggal lengkap tidak tersedia."
                          },
                          "date_of_birth_month": {
                            "type": "integer",
                            "nullable": true,
                            "minimum": 1,
                            "maximum": 12,
                            "description": "Bulan lahir yang dilaporkan registri. Null jika hanya tahun yang diketahui."
                          }
                        }
                      }
                    },
                    "beneficial_owners": {
                      "type": "array",
                      "description": "Pemilik manfaat yang ditemukan melalui pemeriksaan registri, masing-masing diperkaya dengan status sesi KYC turunan dan Skrining AML yang dibuat untuk mereka.",
                      "items": {
                        "type": "object",
                        "properties": {
                          "uuid": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "name": {
                            "type": "string",
                            "description": "Nama lengkap pemilik manfaat (atau nama perusahaan untuk UBO korporasi)."
                          },
                          "first_name": {
                            "type": "string",
                            "nullable": true
                          },
                          "last_name": {
                            "type": "string",
                            "nullable": true
                          },
                          "date_of_birth": {
                            "type": "string",
                            "nullable": true,
                            "description": "Tanggal lahir lengkap jika dilaporkan.",
                            "format": "date"
                          },
                          "country_of_birth": {
                            "type": "string",
                            "nullable": true
                          },
                          "email": {
                            "type": "string",
                            "nullable": true
                          },
                          "company_name": {
                            "type": "string",
                            "nullable": true
                          },
                          "registration_number": {
                            "type": "string",
                            "nullable": true
                          },
                          "entity_type": {
                            "type": "string",
                            "enum": [
                              "person",
                              "company"
                            ]
                          },
                          "nationality": {
                            "type": "string",
                            "nullable": true
                          },
                          "designation": {
                            "type": "string",
                            "nullable": true
                          },
                          "roles": {
                            "type": "array",
                            "description": "Nama peran yang dipegang oleh pemilik ini, mis. `[\"ubo\", \"shareholder\"]`.",
                            "items": {
                              "type": "string"
                            }
                          },
                          "ownership_min_shares": {
                            "type": "string",
                            "nullable": true,
                            "description": "Batas bawah persentase kepemilikan sebagaimana dilaporkan oleh registri. String format bebas (misalnya `\"25\"`, `\"25-50%\"`); gunakan `effective_ownership_percent` untuk nilai numerik yang telah di-parse."
                          },
                          "ownership_max_shares": {
                            "type": "string",
                            "nullable": true,
                            "description": "Batas atas persentase kepemilikan sebagaimana dilaporkan oleh registri. String bentuk bebas; gunakan `effective_ownership_percent` untuk nilai numerik yang diurai."
                          },
                          "is_active": {
                            "type": "boolean"
                          },
                          "aml_status": {
                            "type": "string",
                            "enum": [
                              "Not Finished",
                              "Approved",
                              "Declined",
                              "In Review",
                              "Resub Requested"
                            ],
                            "nullable": true,
                            "description": "Status Skrining AML yang dijalankan untuk pemilik manfaat ini. `null` jika tidak ada Skrining AML yang dijalankan."
                          },
                          "kyc_status": {
                            "type": "string",
                            "enum": [
                              "Not Started",
                              "In Progress",
                              "Approved",
                              "Declined",
                              "In Review",
                              "Expired",
                              "Abandoned",
                              "Kyc Expired",
                              "Resubmitted",
                              "Awaiting User"
                            ],
                            "nullable": true,
                            "description": "Status siklus hidup mentah dari sesi KYC turunan yang dibuat untuk pemilik manfaat ini. Ini adalah enum status sesi lengkap (bukan set ringkas Disetujui/Ditolak/Tertunda). Bernilai `null` jika tidak ada sesi KYC turunan."
                          },
                          "kyc_session_url": {
                            "type": "string",
                            "format": "uri",
                            "nullable": true,
                            "description": "URL yang dapat dibagikan untuk sesi KYC turunan. `null` jika tidak ada sesi turunan."
                          },
                          "kyc_session_id": {
                            "type": "string",
                            "format": "uuid",
                            "nullable": true,
                            "description": "ID sesi dari sesi KYC turunan. Teruskan ke endpoint keputusan yang sama ini untuk mengambil laporan KYC lengkap orang tersebut. Bernilai `null` jika tidak ada sesi turunan."
                          },
                          "verification_workflow_type": {
                            "type": "string",
                            "nullable": true,
                            "description": "Tipe alur kerja dasar dari alur kerja sesi anak (misalnya `kyc`). `null` untuk alur kerja berbasis graf atau saat tidak ada sesi anak."
                          },
                          "verification_workflow_id": {
                            "type": "string",
                            "format": "uuid",
                            "nullable": true,
                            "description": "ID alur kerja yang digunakan oleh sesi anak. Bernilai `null` jika tidak ada sesi anak."
                          },
                          "verification_workflow_label": {
                            "type": "string",
                            "nullable": true,
                            "description": "Label alur kerja sesi turunan yang mudah dibaca manusia. `null` jika tidak diatur."
                          },
                          "verification_workflow_features": {
                            "type": "array",
                            "nullable": true,
                            "description": "Kemajuan per fitur dari sesi verifikasi anak, misalnya `[{\"feature\": \"ID_VERIFICATION\", \"status\": \"Approved\"}]`. `null` ketika sesi anak tidak memiliki daftar fitur yang dapat ditentukan.",
                            "items": {
                              "type": "object",
                              "properties": {
                                "feature": {
                                  "type": "string",
                                  "description": "Nama tampilan fitur (misalnya `ID_VERIFICATION`, `LIVENESS`, `AML`)."
                                },
                                "status": {
                                  "type": "string",
                                  "enum": [
                                    "Not Finished",
                                    "Approved",
                                    "Declined",
                                    "In Review",
                                    "Resub Requested"
                                  ],
                                  "description": "Status tingkat fitur di dalam sesi turunan."
                                }
                              }
                            }
                          },
                          "didit_internal_id": {
                            "type": "string",
                            "nullable": true,
                            "description": "Pengidentifikasi internal stabil dari individu terverifikasi di balik sesi anak — berguna untuk penautan lintas sesi. `null` jika tidak ada sesi anak atau pengguna belum diidentifikasi."
                          },
                          "kyc_document_type": {
                            "type": "string",
                            "nullable": true,
                            "description": "Jenis dokumen yang ditunjukkan dalam sesi KYC turunan (misalnya `P`, `ID`, `DL`). `null` hingga sesi turunan memiliki hasil verifikasi identitas."
                          },
                          "kyc_nationality": {
                            "type": "string",
                            "nullable": true,
                            "description": "Kewarganegaraan diekstraksi dari dokumen dalam sesi KYC anak. `null` hingga tersedia."
                          },
                          "kyc_liveness_passed": {
                            "type": "boolean",
                            "nullable": true,
                            "description": "Apakah pemeriksaan liveness sesi KYC anak berhasil. `null` jika tidak ada pemeriksaan liveness yang dijalankan."
                          },
                          "kyc_verified_at": {
                            "type": "string",
                            "format": "date-time",
                            "nullable": true,
                            "description": "Waktu ketika sesi KYC turunan mencapai `Approved`. `null` selama sesi turunan memiliki status lain."
                          },
                          "kyc_aml_categories": {
                            "type": "object",
                            "nullable": true,
                            "description": "Ringkasan per kategori yang diperoleh dari hit AML orang tersebut. `null` jika tidak ada hit.",
                            "properties": {
                              "sanctions": {
                                "type": "string",
                                "enum": [
                                  "match",
                                  "clear"
                                ]
                              },
                              "pep": {
                                "type": "string",
                                "enum": [
                                  "match",
                                  "clear"
                                ]
                              },
                              "adverse_media": {
                                "type": "string",
                                "enum": [
                                  "match",
                                  "clear"
                                ]
                              },
                              "warnings": {
                                "type": "string",
                                "enum": [
                                  "match",
                                  "clear"
                                ]
                              }
                            }
                          },
                          "kyc_notification_sent_at": {
                            "type": "string",
                            "nullable": true,
                            "description": "Stempel waktu ISO 8601 dari notifikasi undangan verifikasi terakhir yang dikirim untuk sesi turunan orang ini. `null` jika tidak ada yang dikirim."
                          },
                          "child_beneficial_owners": {
                            "type": "array",
                            "description": "Untuk UBO korporat: pemilik manfaat dari entitas pemilik itu sendiri, sebagai objek mentah yang diekstraksi dari registri. Array kosong jika tidak berlaku.",
                            "items": {
                              "type": "object"
                            }
                          },
                          "effective_ownership_percent": {
                            "type": "number",
                            "nullable": true,
                            "description": "Persentase kepemilikan numerik terurai — batas maksimum jika tersedia, jika tidak batas minimum. `null` jika kedua batas tidak dapat diurai."
                          },
                          "voting_min_shares": {
                            "type": "string",
                            "nullable": true
                          },
                          "voting_max_shares": {
                            "type": "string",
                            "nullable": true
                          },
                          "appointment_date": {
                            "type": "string",
                            "nullable": true,
                            "description": "Tanggal penunjukan saat dilaporkan.",
                            "format": "date"
                          }
                        }
                      }
                    }
                  }
                },
                "submitted": {
                  "type": "object",
                  "description": "Pihak yang dikirimkan oleh admin bisnis selama alur Pihak Kunci (baris BusinessParty dengan source=USER).",
                  "properties": {
                    "parties": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "description": "Pihak yang dikirimkan oleh admin bisnis melalui alur Pihak Kunci (source=USER).",
                        "properties": {
                          "uuid": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "entity_type": {
                            "type": "string",
                            "enum": [
                              "person",
                              "company"
                            ]
                          },
                          "source": {
                            "type": "string",
                            "enum": [
                              "USER"
                            ],
                            "description": "Selalu `USER` di sini — wadah ini hanya berisi pihak yang dimasukkan atau dikonfirmasi oleh pengguna akhir dalam alur Pihak Kunci (orang yang ditemukan melalui registri muncul di bawah `registry`)."
                          },
                          "name": {
                            "type": "string"
                          },
                          "first_name": {
                            "type": "string",
                            "nullable": true
                          },
                          "last_name": {
                            "type": "string",
                            "nullable": true
                          },
                          "company_name": {
                            "type": "string",
                            "nullable": true
                          },
                          "registration_number": {
                            "type": "string",
                            "nullable": true
                          },
                          "email": {
                            "type": "string",
                            "format": "email",
                            "nullable": true
                          },
                          "nationality": {
                            "type": "string",
                            "nullable": true,
                            "description": "Kewarganegaraan untuk perorangan; negara pendirian untuk pihak perusahaan."
                          },
                          "phone_number": {
                            "type": "string",
                            "nullable": true
                          },
                          "date_of_birth": {
                            "type": "string",
                            "format": "date",
                            "nullable": true
                          },
                          "position": {
                            "type": "string",
                            "nullable": true,
                            "description": "Jabatan/posisi berupa teks bebas (khusus individu)."
                          },
                          "custom_fields": {
                            "type": "object",
                            "description": "Kolom kustom yang ditentukan alur kerja yang dikumpulkan untuk pihak ini; kunci ditentukan oleh deskriptor kolom pihak kunci alur kerja."
                          },
                          "is_active": {
                            "type": "boolean"
                          },
                          "is_skipped": {
                            "type": "boolean",
                            "description": "True saat pengguna akhir melewati verifikasi untuk pihak ini (hanya dimungkinkan jika peran mengizinkan untuk dilewati)."
                          },
                          "requires_verification": {
                            "type": "boolean",
                            "description": "True saat sub-sesi KYC / KYB turunan diperlukan untuk pihak ini berdasarkan pengaturan peran dan ambang batas kepemilikan."
                          },
                          "roles": {
                            "type": "array",
                            "description": "Semua peran yang dipegang oleh pihak ini, masing-masing dengan persentase kepemilikan dan hak suaranya sendiri. Tidak ada `role`/`ownership_percent` skalar pada pihak itu sendiri.",
                            "items": {
                              "type": "object",
                              "properties": {
                                "role": {
                                  "type": "string",
                                  "enum": [
                                    "director",
                                    "non_executive_director",
                                    "secretary",
                                    "chairman",
                                    "ubo",
                                    "shareholder",
                                    "representative",
                                    "founder",
                                    "legal_advisor",
                                    "authorized_signatory",
                                    "trustee",
                                    "beneficiary",
                                    "settlor",
                                    "protector",
                                    "company_officer",
                                    "investor",
                                    "other"
                                  ]
                                },
                                "ownership_percent": {
                                  "type": "number",
                                  "nullable": true
                                },
                                "voting_percent": {
                                  "type": "number",
                                  "nullable": true
                                }
                              }
                            }
                          },
                          "kyc_session_id": {
                            "type": "string",
                            "format": "uuid",
                            "nullable": true,
                            "description": "ID sesi KYC turunan untuk pihak perorangan yang memerlukan verifikasi. Bernilai `null` jika tidak."
                          },
                          "kyc_session_status": {
                            "type": "string",
                            "enum": [
                              "Not Started",
                              "In Progress",
                              "Approved",
                              "Declined",
                              "In Review",
                              "Expired",
                              "Abandoned",
                              "Kyc Expired",
                              "Resubmitted",
                              "Awaiting User"
                            ],
                            "nullable": true,
                            "description": "Status siklus hidup sesi KYC turunan. `null` jika tidak ada sesi KYC turunan."
                          },
                          "kyc_session_url": {
                            "type": "string",
                            "format": "uri",
                            "nullable": true
                          },
                          "kyb_sub_session_id": {
                            "type": "string",
                            "format": "uuid",
                            "nullable": true,
                            "description": "ID sub-sesi KYB turunan untuk pihak korporasi yang memerlukan verifikasi. Bernilai `null` jika tidak."
                          },
                          "kyb_sub_session_status": {
                            "type": "string",
                            "enum": [
                              "Not Started",
                              "In Progress",
                              "Approved",
                              "Declined",
                              "In Review",
                              "Expired",
                              "Abandoned",
                              "Kyc Expired",
                              "Resubmitted",
                              "Awaiting User"
                            ],
                            "nullable": true,
                            "description": "Status siklus hidup sub-sesi KYB turunan. `null` jika tidak ada sub-sesi."
                          },
                          "kyb_sub_session_url": {
                            "type": "string",
                            "format": "uri",
                            "nullable": true,
                            "description": "URL yang dapat dibagikan untuk sub-sesi KYB turunan. `null` jika tidak ada sub-sesi."
                          },
                          "verification_workflow_type": {
                            "type": "string",
                            "nullable": true,
                            "description": "Tipe alur kerja dasar dari alur kerja sesi anak (sesi KYC lebih diutamakan, beralih ke sub-sesi KYB). `null` untuk alur kerja berbasis graf atau saat tidak ada sesi anak."
                          },
                          "verification_workflow_id": {
                            "type": "string",
                            "format": "uuid",
                            "nullable": true,
                            "description": "ID alur kerja yang digunakan oleh sesi anak. Bernilai `null` jika tidak ada sesi anak."
                          },
                          "verification_workflow_label": {
                            "type": "string",
                            "nullable": true,
                            "description": "Label alur kerja sesi turunan yang mudah dibaca manusia. `null` jika tidak diatur."
                          },
                          "verification_workflow_features": {
                            "type": "array",
                            "nullable": true,
                            "description": "Kemajuan per fitur dari sesi verifikasi anak, misalnya `[{\"feature\": \"ID_VERIFICATION\", \"status\": \"Approved\"}]`. `null` ketika sesi anak tidak memiliki daftar fitur yang dapat ditentukan.",
                            "items": {
                              "type": "object",
                              "properties": {
                                "feature": {
                                  "type": "string",
                                  "description": "Nama tampilan fitur (misalnya `ID_VERIFICATION`, `LIVENESS`, `AML`)."
                                },
                                "status": {
                                  "type": "string",
                                  "enum": [
                                    "Not Finished",
                                    "Approved",
                                    "Declined",
                                    "In Review",
                                    "Resub Requested"
                                  ],
                                  "description": "Status tingkat fitur di dalam sesi turunan."
                                }
                              }
                            }
                          },
                          "didit_internal_id": {
                            "type": "string",
                            "nullable": true,
                            "description": "Pengidentifikasi internal stabil dari individu terverifikasi di balik sesi anak. `null` jika belum diidentifikasi."
                          }
                        }
                      }
                    }
                  }
                },
                "ubo_kyc_summary": {
                  "type": "object",
                  "nullable": true,
                  "description": "Progres KYC UBO agregat, atau null jika tidak ada UBO yang memiliki sesi KYC tertaut.",
                  "properties": {
                    "total": {
                      "type": "integer"
                    },
                    "approved": {
                      "type": "integer"
                    },
                    "flagged": {
                      "type": "integer",
                      "description": "UBO yang status KYC-nya Ditolak atau Dalam Peninjauan."
                    },
                    "pending": {
                      "type": "integer"
                    }
                  }
                },
                "warnings": {
                  "type": "array",
                  "items": {
                    "type": "object"
                  }
                }
              }
            }
          },
          "document_verifications": {
            "type": "array",
            "nullable": true,
            "description": "Pemeriksaan verifikasi dokumen dikelompokkan berdasarkan node alur kerja. Hanya ada jika `session_kind = business`.",
            "items": {
              "type": "object",
              "description": "Dokumen dikelompokkan berdasarkan node alur kerja. Hanya ada jika session_kind = business.",
              "properties": {
                "status": {
                  "type": "string"
                },
                "node_id": {
                  "type": "string",
                  "nullable": true
                },
                "items": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "uuid": {
                        "type": "string",
                        "format": "uuid"
                      },
                      "document_type": {
                        "type": "string",
                        "enum": [
                          "LEGAL_PRESENCE",
                          "COMPANY_DETAILS",
                          "OWNERSHIP_STRUCTURE",
                          "REPRESENTATIVES_AUTHORIZATION",
                          "OTHER"
                        ],
                        "nullable": true,
                        "description": "Grup dokumen KYB tingkat tinggi tempat file diklasifikasikan. `null` jika belum diklasifikasikan."
                      },
                      "document_subtype": {
                        "type": "string",
                        "nullable": true,
                        "description": "Subtipe spesifik yang terdeteksi OCR (misalnya `CERTIFICATE_OF_INCORPORATION`, `SHAREHOLDER_REGISTRY`); `UNKNOWN` jika OCR tidak dapat mengklasifikasikan dokumen dengan meyakinkan."
                      },
                      "document_group": {
                        "type": "string",
                        "enum": [
                          "LEGAL_PRESENCE",
                          "COMPANY_DETAILS",
                          "OWNERSHIP_STRUCTURE",
                          "REPRESENTATIVES_AUTHORIZATION",
                          "OTHER"
                        ],
                        "nullable": true,
                        "description": "Alias dari `document_type` — nama grup yang digunakan oleh `groups` dan `required_groups`."
                      },
                      "file_url": {
                        "type": "string",
                        "format": "uri",
                        "nullable": true,
                        "description": "Tautan presigned berdurasi singkat ke file yang diunggah. `null` untuk placeholder permintaan dokumen yang dibuat analis (`is_requested = true`) yang belum dipenuhi."
                      },
                      "original_filename": {
                        "type": "string",
                        "nullable": true,
                        "description": "Nama file seperti yang diunggah oleh pengguna atau analis."
                      },
                      "file_size": {
                        "type": "integer",
                        "nullable": true,
                        "description": "Ukuran file dalam byte."
                      },
                      "status": {
                        "type": "string",
                        "enum": [
                          "Not Finished",
                          "Approved",
                          "Declined",
                          "In Review",
                          "Resub Requested"
                        ],
                        "description": "Status verifikasi per dokumen."
                      },
                      "created_at": {
                        "type": "string",
                        "format": "date-time"
                      },
                      "cross_check_result": {
                        "type": "object",
                        "nullable": true,
                        "description": "Referensi silang dari kolom dokumen yang diekstraksi OCR terhadap profil perusahaan di registri. Sebuah objek dengan bagian `critical`, `non_critical`, dan `people`, masing-masing memetakan nama kolom (misalnya `company_name`, `registration_number`, `incorporation_date`, `registered_address`) ke catatan perbandingan seperti `{\"document\": \"...\", \"registry\": \"...\", \"match\": true, \"score\": 0.97}`. Bernilai `null` jika dokumen tidak memiliki data OCR atau tidak ada perusahaan registri untuk dibandingkan."
                      },
                      "document_metadata": {
                        "type": "object",
                        "nullable": true,
                        "description": "Metadata yang diekstraksi dari dokumen perusahaan yang diunggah. Jika ekstraksi metadata berhasil, ke-16 kunci selalu ada (nilai individual bernilai `null` jika tidak berlaku untuk jenis file); seluruh objek bernilai `null` jika tidak ada yang dapat diekstraksi. Untuk PDF, `overlay_manipulation` memuat analisis teks overlay forensik.",
                        "properties": {
                          "file_size": {
                            "type": "integer",
                            "nullable": true,
                            "description": "Ukuran dokumen."
                          },
                          "content_type": {
                            "type": "string",
                            "nullable": true,
                            "description": "Tipe konten dokumen."
                          },
                          "creation_date": {
                            "type": "string",
                            "nullable": true,
                            "description": "Tanggal saat dokumen dibuat."
                          },
                          "modified_date": {
                            "type": "string",
                            "nullable": true,
                            "description": "Tanggal saat dokumen dimodifikasi."
                          },
                          "creator": {
                            "type": "string",
                            "nullable": true,
                            "description": "Alat/pengguna pembuat yang tercatat dalam metadata file (`Creator` PDF)."
                          },
                          "producer": {
                            "type": "string",
                            "nullable": true,
                            "description": "Perangkat lunak yang menghasilkan file (`Producer` PDF)."
                          },
                          "software": {
                            "type": "string",
                            "nullable": true,
                            "description": "Perangkat lunak pengeditan yang tercatat dalam metadata file."
                          },
                          "encryption": {
                            "type": "string",
                            "nullable": true,
                            "description": "Skema enkripsi berkas, jika terenkripsi."
                          },
                          "is_signed": {
                            "type": "boolean",
                            "nullable": true,
                            "description": "Apakah dokumen memiliki tanda tangan digital."
                          },
                          "is_tampered": {
                            "type": "boolean",
                            "nullable": true,
                            "description": "Apakah tanda tangan digital gagal dalam validasi (modifikasi setelah penandatanganan)."
                          },
                          "signature_info": {
                            "type": "object",
                            "nullable": true,
                            "description": "Rincian tanda tangan digital, jika ada."
                          },
                          "exif_original_date": {
                            "type": "string",
                            "nullable": true,
                            "description": "Tanggal pengambilan asli EXIF, untuk unggahan gambar."
                          },
                          "exif_digitized_date": {
                            "type": "string",
                            "nullable": true,
                            "description": "Tanggal digitalisasi EXIF, untuk unggahan gambar."
                          },
                          "processed_by_known_editor": {
                            "type": "boolean",
                            "nullable": true,
                            "description": "Menentukan apakah metadata menunjukkan file telah melewati editor gambar/PDF yang dikenal."
                          },
                          "has_different_creation_mod_date": {
                            "type": "boolean",
                            "nullable": true,
                            "description": "Menentukan apakah tanggal pembuatan dan modifikasi berbeda — kemungkinan sinyal pengeditan (tetapi tidak konklusif)."
                          },
                          "overlay_manipulation": {
                            "type": "object",
                            "nullable": true,
                            "description": "Analisis forensik PDF untuk dugaan manipulasi teks overlay. Bernilai null jika tidak ditemukan bukti manipulasi overlay atau dokumen bukan berupa PDF.",
                            "properties": {
                              "detected": {
                                "type": "boolean",
                                "description": "Menentukan apakah bukti manipulasi teks overlay terdeteksi."
                              },
                              "analyzed": {
                                "type": "boolean",
                                "description": "Apakah PDF dapat dianalisis."
                              },
                              "analysis_incomplete": {
                                "type": "boolean",
                                "description": "Ada dan bernilai true hanya jika file tidak dapat diperiksa sepenuhnya. Bagian yang berhasil diperiksa tetap menampilkan temuannya jika memungkinkan, dan dokumen memunculkan peringatan penggantian teks yang belum terbukti."
                              },
                              "signals": {
                                "type": "array",
                                "items": {
                                  "type": "string"
                                },
                                "description": "Sinyal forensik yang terpicu, seperti duplicate_font_subset atau glyph_fragmentation."
                              },
                              "manipulated_regions": {
                                "type": "array",
                                "description": "Area yang diduga dimanipulasi dalam koordinat halaman PDF.",
                                "items": {
                                  "type": "object",
                                  "properties": {
                                    "page": {
                                      "type": "integer"
                                    },
                                    "x": {
                                      "type": "number"
                                    },
                                    "y": {
                                      "type": "number"
                                    },
                                    "width": {
                                      "type": "number"
                                    },
                                    "height": {
                                      "type": "number"
                                    },
                                    "page_width": {
                                      "type": "number"
                                    },
                                    "page_height": {
                                      "type": "number"
                                    }
                                  }
                                }
                              }
                            }
                          }
                        }
                      },
                      "description": {
                        "type": "string",
                        "nullable": true,
                        "description": "Label atau alasan yang diberikan analis untuk permintaan dokumen. `null` untuk unggahan reguler."
                      },
                      "is_requested": {
                        "type": "boolean",
                        "description": "True untuk placeholder permintaan dokumen yang dibuat analis yang menunggu pengunggahan."
                      },
                      "ocr_data": {
                        "type": "object",
                        "nullable": true
                      },
                      "is_console_upload": {
                        "type": "boolean",
                        "description": "True untuk dokumen yang diunggah dari konsol alih-alih dari alur pengguna akhir. Unggahan konsol tidak pernah mengubah status agregat tingkat fitur."
                      },
                      "is_confirmed": {
                        "type": "boolean",
                        "description": "Unggahan konsol dimulai dengan `false` dan beralih ke `true` setelah admin mengonfirmasinya; unggahan pengguna akhir selalu `true`."
                      }
                    }
                  }
                },
                "groups": {
                  "type": "object",
                  "description": "Penghitung progres per grup yang diindeks berdasarkan nama grup (misalnya legal_presence, ownership_structure).",
                  "additionalProperties": {
                    "type": "object",
                    "properties": {
                      "total": {
                        "type": "integer"
                      },
                      "approved": {
                        "type": "integer"
                      },
                      "pending": {
                        "type": "integer"
                      },
                      "declined": {
                        "type": "integer"
                      },
                      "in_review": {
                        "type": "integer"
                      },
                      "other": {
                        "type": "integer"
                      },
                      "missing": {
                        "type": "integer",
                        "description": "Placeholder yang diminta yang belum ada file yang diunggah."
                      }
                    }
                  }
                },
                "required_groups": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                },
                "warnings": {
                  "type": "array",
                  "items": {
                    "type": "object"
                  }
                }
              }
            }
          },
          "environment": {
            "type": "string",
            "enum": [
              "live",
              "sandbox"
            ],
            "description": "Apakah sesi dibuat oleh aplikasi live (`live`) atau aplikasi sandbox (`sandbox`). Sesi sandbox gratis, disimulasikan sepenuhnya, dan tidak pernah membebankan kredit."
          },
          "sandbox_scenario": {
            "type": "string",
            "nullable": true,
            "description": "Skenario sandbox yang digunakan saat membuat sesi. Bernilai `null` untuk sesi produksi dan untuk sesi sandbox yang dibuat tanpanya."
          },
          "resubmissions": {
            "type": "array",
            "description": "Hanya dikembalikan dengan `include=resubmissions`, untuk sesi pengguna dan bisnis. Satu entri per permintaan pengiriman ulang, terlama terlebih dahulu. Setiap entri memuat hasil yang dikembalikan oleh langkah-langkah yang dikirimkan ulang sebelum permintaan, sehingga pengiriman sebelumnya tetap dapat dibaca. Menghapus sesi akan menghapus setiap pengiriman.",
            "items": {
              "type": "object",
              "properties": {
                "number": {
                  "type": "integer",
                  "description": "1 untuk pengiriman ulang pertama pada sesi ini, 2 untuk yang kedua, dan seterusnya."
                },
                "created_at": {
                  "type": "string",
                  "format": "date-time",
                  "description": "Waktu pengiriman ulang diminta."
                },
                "previous_status": {
                  "type": "string",
                  "description": "Status sesi tepat sebelum permintaan."
                },
                "nodes": {
                  "type": "array",
                  "description": "Langkah-langkah alur kerja yang dikirimkan kembali kepada pengguna.",
                  "items": {
                    "type": "object",
                    "properties": {
                      "node_id": {
                        "type": "string"
                      },
                      "feature": {
                        "type": "string"
                      }
                    }
                  }
                },
                "reasons": {
                  "type": "object",
                  "nullable": true,
                  "additionalProperties": {
                    "type": "string"
                  },
                  "description": "Alasan yang diberikan untuk setiap langkah, dengan kunci berdasarkan `node_id`."
                },
                "requested_by": {
                  "type": "object",
                  "nullable": true,
                  "description": "Pihak yang meminta pengajuan ulang.",
                  "properties": {
                    "name": {
                      "type": "string"
                    },
                    "email": {
                      "type": "string"
                    },
                    "type": {
                      "type": "string"
                    }
                  }
                },
                "results": {
                  "type": "object",
                  "additionalProperties": true,
                  "description": "Hasil yang dikembalikan oleh langkah-langkah yang dikirim ulang sebelum permintaan, dengan kunci yang sama dan dalam bentuk yang sama seperti hasil saat ini dari respons ini (`id_verifications`, `nfc_verifications`, `liveness_checks`, `face_matches`, `poa_verifications`, `phone_verifications`, `email_verifications`, `aml_screenings`, `ip_analyses`, `database_validations`, `questionnaire_responses`, `document_ai_documents`, `geolocation_checks`; untuk sesi bisnis juga `document_verifications`). Hanya kunci dari langkah-langkah yang dikirimkan kembali yang akan muncul."
                }
              }
            }
          },
          "biometric_consent": {
            "type": "object",
            "nullable": true,
            "description": "Apakah sesi memerlukan persetujuan biometrik eksplisit sebelum pengambilan wajah, alasannya, dan bukti jawabannya. Hanya sesi Verifikasi Pengguna (KYC); objek yang sama berada di dalam `decision` pada webhook sesi. Bernilai `null` jika sesi tidak pernah dievaluasi, misalnya alur kerja tanpa pengambilan wajah. Kolom tanpa nilai yang tercatat bernilai `null`. SDK native di bawah 4.10.0, atau yang tidak melaporkan versinya, tidak dapat menampilkan langkah persetujuan: pengambilan wajahnya berjalan seperti sebelumnya, dan sesi yang memerlukan persetujuan kemudian melaporkan `status: \"pending\"` dengan `reason: \"BIOMETRIC_CONSENT_UNSUPPORTED_SDK\"`. Lihat [Persetujuan biometrik](/id/getting-started/biometric-consent).",
            "properties": {
              "required": {
                "type": "boolean",
                "description": "Whether the session must collect explicit biometric consent. Never goes back to `false`."
              },
              "trigger": {
                "type": "string",
                "nullable": true,
                "enum": [
                  "declared_state",
                  "ip_state",
                  "ip_unknown",
                  "document_issuer",
                  "forced",
                  "customer_collected"
                ],
                "description": "Alasan mengapa persetujuan diperlukan, atau bagaimana persyaratan persetujuan dipenuhi. `declared_state`: Anda mendeklarasikan negara bagian yang dicakup (`user_state`, atau alamat AS di `expected_details`). `ip_state`: IP pengguna berada di negara bagian yang dicakup (Illinois, Texas, Colorado). `ip_unknown`: bukti menunjukkan pengguna berada di AS tetapi negara bagian tidak dapat dipastikan (IP berada di AS tanpa informasi negara bagian, atau lokasinya tidak dapat ditentukan sementara detail Anda atau dokumen menempatkan pengguna di AS). `document_issuer`: dokumen identitas diterbitkan oleh negara bagian yang dicakup. `forced`: mode aplikasi adalah Always. `customer_collected`: Anda mengirimkan `biometric_consent` saat membuat sesi. `null` jika tidak diperlukan."
              },
              "status": {
                "type": "string",
                "enum": [
                  "not_required",
                  "pending",
                  "given",
                  "declined"
                ],
                "description": "`not_required`; `pending` (diperlukan dan tidak diberikan: orang tersebut belum menjawab, atau `reason` menjelaskan mengapa data tidak dikumpulkan); `given`; `declined` (penolakan dicatat dan sesi berakhir sebagai `Declined`; saat ini tidak ada layar Didit yang menawarkan penolakan)."
              },
              "given_at": {
                "type": "string",
                "format": "date-time",
                "nullable": true,
                "description": "Saat persetujuan diberikan. Untuk `customer_collected`, nilai `given_at` yang Anda kirimkan."
              },
              "declined_at": {
                "type": "string",
                "format": "date-time",
                "nullable": true,
                "description": "Saat penolakan dicatat."
              },
              "text_version": {
                "type": "string",
                "nullable": true,
                "description": "ID versi dari teks persetujuan yang dijawab oleh individu tersebut, atau yang Anda kirimkan."
              },
              "text_hash": {
                "type": "string",
                "nullable": true,
                "description": "SHA-256 (heksadesimal) dari teks persetujuan persis seperti yang ditampilkan, dalam bahasa teks tersebut ditampilkan."
              },
              "locale": {
                "type": "string",
                "nullable": true,
                "description": "Bahasa yang digunakan untuk menampilkan teks persetujuan."
              },
              "policy_url": {
                "type": "string",
                "format": "uri",
                "nullable": true,
                "description": "Kebijakan data biometrik yang ditautkan oleh langkah persetujuan."
              },
              "step": {
                "type": "string",
                "nullable": true,
                "description": "Langkah alur kerja tempat sesi berada saat orang tersebut menjawab, misalnya `LIVENESS`."
              },
              "node_id": {
                "type": "string",
                "nullable": true,
                "description": "Node graf alur kerja tempat sesi berada saat orang tersebut menjawab."
              },
              "ip_address": {
                "type": "string",
                "nullable": true,
                "description": "IP asal jawaban."
              },
              "ip_country_code": {
                "type": "string",
                "nullable": true,
                "description": "Negara ISO 3166-1 alpha-2 dari IP jawaban."
              },
              "ip_state": {
                "type": "string",
                "nullable": true,
                "description": "Subdivisi ISO 3166-2 dari IP pada jawaban, misalnya `US-IL`."
              },
              "ip_city": {
                "type": "string",
                "nullable": true,
                "description": "Kota dari IP jawaban."
              },
              "user_agent": {
                "type": "string",
                "nullable": true,
                "description": "User agent dari permintaan jawaban."
              },
              "detected_ip_address": {
                "type": "string",
                "nullable": true,
                "description": "IP orang tersebut yang digunakan saat persyaratan terakhir dievaluasi. Dapat berbeda dari `ip_address` jika orang tersebut menjawab di perangkat lain."
              },
              "detected_country_code": {
                "type": "string",
                "nullable": true,
                "description": "Negara ISO 3166-1 alpha-2 dari IP yang terdeteksi."
              },
              "detected_state": {
                "type": "string",
                "nullable": true,
                "description": "Subdivisi ISO 3166-2 dari IP yang terdeteksi."
              },
              "detected_city": {
                "type": "string",
                "nullable": true,
                "description": "Kota dari IP yang terdeteksi."
              },
              "declared_state": {
                "type": "string",
                "nullable": true,
                "description": "Subdivisi ISO 3166-2 yang Anda nyatakan: `user_state`, atau negara bagian dari alamat AS di `expected_details`."
              },
              "document_state": {
                "type": "string",
                "nullable": true,
                "description": "Subdivisi ISO 3166-2 yang menerbitkan dokumen identitas, dibaca saat pengambilan ID."
              },
              "jurisdictions": {
                "type": "array",
                "items": {
                  "type": "string"
                },
                "description": "Negara bagian AS (kode USPS, misalnya `IL`) yang undang-undang biometriknya mencakup orang tersebut. `US` jika bukti menunjukkan orang tersebut berada di AS tetapi negara bagiannya tidak diketahui. Kosong jika tidak ada yang berlaku."
              },
              "retention_months": {
                "type": "integer",
                "nullable": true,
                "description": "Batas retensi biometrik terpendek, dalam bulan, di antara `jurisdictions`. `null` jika tidak ada yang berlaku."
              },
              "reason": {
                "type": "string",
                "nullable": true,
                "enum": [
                  "BIOMETRIC_CONSENT_UNSUPPORTED_SDK",
                  "BIOMETRIC_CONSENT_DECLINED"
                ],
                "description": "`BIOMETRIC_CONSENT_UNSUPPORTED_SDK`: persetujuan diperlukan dan SDK native di bawah versi 4.10.0, atau yang tidak melaporkan versinya, mengambil wajah tanpa langkah persetujuan; `status` tetap `pending`, atau `given` jika orang tersebut kemudian setuju dalam alur yang di-hosting. `BIOMETRIC_CONSENT_DECLINED`: penolakan dicatat (menggantikan alasan SDK). `null` jika tidak, dan selalu `null` ketika sesi tidak memerlukan persetujuan."
              },
              "decline_reason": {
                "type": "string",
                "nullable": true,
                "enum": [
                  "BIOMETRIC_CONSENT_DECLINED"
                ],
                "description": "`BIOMETRIC_CONSENT_DECLINED` ketika penolakan yang tercatat mengakhiri sesi, jika tidak maka `null`."
              },
              "face_data_deleted_at": {
                "type": "string",
                "format": "date-time",
                "nullable": true,
                "description": "Waktu ketika penolakan menghapus gambar wajah, video, dan templat wajah sesi. `null` kecuali jika penolakan telah dicatat."
              }
            }
          },
          "investigator": {
            "$ref": "#/components/schemas/InvestigatorBlock"
          },
          "biometric_retention": {
            "$ref": "#/components/schemas/BiometricRetention"
          },
          "fraud_check": {
            "type": "object",
            "nullable": true,
            "additionalProperties": true,
            "description": "Hasil dari panggilan API Fraud Check. `null` untuk setiap sesi lainnya."
          },
          "full_session_video": {
            "type": "string",
            "format": "uri",
            "nullable": true,
            "description": "URL rekaman sesi penuh yang akan kedaluwarsa. Hanya dikembalikan saat organisasi Anda merekam video sesi penuh."
          },
          "full_session_video_recorded_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Waktu ketika rekaman sesi lengkap dibuat. Hanya dikembalikan jika organisasi Anda merekam video sesi lengkap."
          }
        }
      },
      "WorkflowDetail": {
        "type": "object",
        "description": "Kolom di bawah ini memiliki tipe; objek ini juga memuat setiap kolom lain dari konfigurasi alur kerja (pengalih fitur, ambang batas, tindakan peringatan, dokumen yang diizinkan, callback) sebagai properti tambahan. Kolom yang tidak berlaku untuk `workflow_type` bernilai `null`.",
        "properties": {
          "uuid": {
            "type": "string",
            "format": "uuid",
            "description": "Pengidentifikasi per versi (`settings_uuid`). Setiap versi alur kerja memiliki pengidentifikasi tersendiri."
          },
          "workflow_id": {
            "type": "string",
            "format": "uuid",
            "description": "Pengidentifikasi stabil yang digunakan bersama oleh setiap versi alur kerja. Sesi yang dibuat dengannya menggunakan versi terbaru yang dipublikasikan."
          },
          "workflow_label": {
            "type": "string",
            "description": "Nama tampilan alur kerja."
          },
          "workflow_type": {
            "type": "string",
            "nullable": true,
            "enum": [
              "kyc",
              "kyb",
              "adaptive_age_verification",
              "biometric_authentication",
              "address_verification",
              "questionnaire_verification",
              "email_verification",
              "phone_verification",
              null
            ],
            "description": "Templat alur kerja. `null` untuk alur kerja graf yang dibuat tanpa templat."
          },
          "is_default": {
            "type": "boolean",
            "description": "Apakah ini merupakan alur kerja default aplikasi."
          },
          "is_archived": {
            "type": "boolean",
            "description": "Alur kerja yang diarsipkan tidak dapat memulai sesi baru."
          },
          "version": {
            "type": "integer",
            "description": "Nomor versi dalam alur kerja."
          },
          "status": {
            "type": "string",
            "enum": [
              "draft",
              "published"
            ],
            "description": "Versi draf dapat diedit; versi yang dipublikasikan bersifat tidak dapat diubah dan digunakan untuk sesi baru."
          },
          "published_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Kapan versi ini dipublikasikan. `null` untuk draf."
          },
          "is_simple_workflow": {
            "type": "boolean",
            "description": "`true` saat alur kerja tidak memiliki `workflow_graph` khusus."
          },
          "is_editable": {
            "type": "boolean",
            "description": "`true` hanya untuk versi `draft`."
          },
          "workflow_url": {
            "type": "string",
            "format": "uri",
            "description": "URL publik yang memulai sesi dengan alur kerja ini."
          },
          "workflow_graph": {
            "type": "object",
            "nullable": true,
            "additionalProperties": true,
            "description": "Struktur graf alur kerja (node dan edge). `null` untuk alur kerja sederhana."
          },
          "features": {
            "type": "string",
            "description": "Fitur yang diaktifkan digabungkan dengan `\" + \"`, misalnya `\"OCR + LIVENESS\"`."
          },
          "total_price": {
            "type": "number",
            "nullable": true,
            "description": "Harga per sesi; untuk alur kerja graf, merupakan jalur termahal."
          },
          "min_price": {
            "type": "number",
            "nullable": true,
            "description": "Harga jalur termurah melalui alur kerja."
          },
          "max_price": {
            "type": "number",
            "nullable": true,
            "description": "Harga jalur termahal melalui alur kerja."
          },
          "special_add_on_prices": {
            "type": "object",
            "nullable": true,
            "additionalProperties": true,
            "description": "Harga add-on khusus organisasi, atau `null` jika tidak ada yang diatur."
          },
          "max_retry_attempts": {
            "type": "integer",
            "description": "Jumlah coba lagi yang diizinkan setelah verifikasi ditolak."
          },
          "retry_window_days": {
            "type": "integer",
            "nullable": true,
            "description": "Jumlah hari selama percobaan ulang diizinkan."
          },
          "session_expiration_time": {
            "type": "integer",
            "description": "Detik sebelum sesi yang belum selesai kedaluwarsa."
          },
          "questionnaire": {
            "type": "object",
            "nullable": true,
            "additionalProperties": true,
            "description": "Kuesioner yang dilampirkan pada alur kerja, atau `null`."
          },
          "kyb_role_settings": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true
            },
            "description": "Pengaturan verifikasi per peran untuk pihak kunci KYB."
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          },
          "signature_availability": {
            "type": "object",
            "description": "Tingkat Tanda Tangan Elektronik mana yang dapat digunakan untuk menandatangani saat ini. Periksa ini sebelum Anda menyetel `signature_level`. Dikembalikan pada alur kerja `kyc`, `kyb`, dan graf.",
            "properties": {
              "simple": {
                "type": "boolean",
                "description": "Simple selalu tersedia."
              },
              "aes": {
                "type": "boolean",
                "description": "Menentukan apakah Tingkat Lanjut (AES) dapat menandatangani sekarang. Saat bernilai `false`, penyimpanan langkah baru pada `signature_level: \"aes\"` ditolak dengan `aes_not_available`."
              },
              "qes": {
                "type": "boolean",
                "description": "Menentukan apakah Berkualifikasi (QES) dapat menandatangani sekarang. Nilainya adalah `false` sampai penyedia yang berkualifikasi terhubung."
              }
            }
          },
          "is_bank_verification_enabled": {
            "type": "boolean",
            "description": "Menentukan apakah alur kerja KYC atau KYB sederhana menjalankan verifikasi Bank. Verifikasi ini berjalan setelah langkah kontak (dan verifikasi Lokasi) dan sebelum validasi database, AML, serta analisis IP. Verifikasi Bank belum tersedia secara umum: mengaktifkannya ditolak di mana pun fitur ini belum diaktifkan."
          },
          "bank_verification_config": {
            "type": "object",
            "additionalProperties": true,
            "description": "Pengaturan verifikasi bank dari alur kerja sederhana, dengan kunci yang sama seperti yang diterima node `BANK_VERIFICATION` (misalnya `bank_countries` dan `bank_method_order`). Kunci yang tidak dikenal akan dibuang. Setiap kunci bersifat opsional dan kunci yang tidak ada akan menggunakan nilai default-nya, sehingga `{}` berarti semua nilai default. Lihat [Pengaturan verifikasi bank](/id/management-api/workflows/feature-configs#verifikasi-bank).",
            "example": {}
          },
          "is_geolocation_enabled": {
            "type": "boolean",
            "description": "Menentukan apakah alur kerja KYC sederhana menjalankan verifikasi Lokasi. Verifikasi ini berjalan setelah langkah kontak dan sebelum verifikasi Bank serta validasi database. Alur kerja Bisnis (KYB) tidak dapat menjalankannya."
          },
          "geolocation_config": {
            "type": "object",
            "additionalProperties": true,
            "description": "Pengaturan verifikasi lokasi dari alur kerja sederhana, dengan kunci yang sama seperti yang diterima node `GEOLOCATION` (misalnya `is_geolocation_geofencing_enabled` dan `geolocation_max_attempts`). Kunci yang tidak dikenal akan diabaikan. Setiap kunci bersifat opsional dan kunci yang tidak ada akan menggunakan nilai default-nya, sehingga `{}` berarti semua nilai default.",
            "example": {}
          }
        },
        "additionalProperties": true
      },
      "UserSessionListItem": {
        "title": "KYC session row (session_kind: user)",
        "type": "object",
        "description": "Baris ringkasan untuk sesi Verifikasi Pengguna (KYC). Kolom identitas (`full_name`, `country`, `document_type`, `portrait_image`, kolom kontak) diisi secara bertahap saat pengguna menyelesaikan langkah verifikasi, dan bernilai `null` hingga langkah terkait selesai. Kolom yang dibatasi oleh konfigurasi atribut respons alur kerja juga dikembalikan sebagai `null`.",
        "required": [
          "session_id",
          "session_kind",
          "session_number",
          "session_url",
          "portrait_image",
          "document_type",
          "full_name",
          "country",
          "status",
          "vendor_data",
          "didit_internal_id",
          "created_at",
          "features",
          "phone_number",
          "email_address",
          "additional_details"
        ],
        "properties": {
          "session_id": {
            "type": "string",
            "format": "uuid",
            "description": "Pengenal unik sesi verifikasi. Gunakan dengan `GET /v3/session/{sessionId}/decision/` untuk mengambil seluruh payload keputusan.",
            "example": "5b3720ed-d429-42ef-b67f-37ea805f48ee"
          },
          "session_kind": {
            "type": "string",
            "enum": [
              "user"
            ],
            "description": "Diskriminator baris. Selalu `\"user\"` untuk baris KYC; baris Verifikasi Bisnis (KYB) memiliki `\"business\"` dan bentuk yang berbeda.",
            "example": "user"
          },
          "session_number": {
            "type": "integer",
            "description": "Nomor urut sesi yang mudah dibaca manusia di dalam aplikasi Anda. Juga dicocokkan oleh parameter `search`.",
            "example": 720
          },
          "session_url": {
            "type": "string",
            "nullable": true,
            "description": "URL verifikasi yang di-hosting yang dibuka pengguna akhir untuk menyelesaikan alur. `null` jika sesi tidak memiliki URL yang di-hosting.",
            "example": "https://verify.didit.me/session/CuXoBYCYVO5Y"
          },
          "portrait_image": {
            "type": "string",
            "nullable": true,
            "description": "URL presigned yang akan kedaluwarsa dari foto potret terbaik yang tersedia: foto chip NFC jika tersedia, jika tidak foto potret dokumen identitas, jika tidak gambar referensi liveness. `null` hingga salah satunya ada. Unduh dengan segera; tautan akan kedaluwarsa.",
            "example": "https://<media-host>/portraits/5b3720ed.jpg?X-Amz-Expires=3600&X-Amz-Signature=..."
          },
          "document_type": {
            "type": "string",
            "nullable": true,
            "enum": [
              "Passport",
              "Identity Card",
              "Driver's License",
              "Residence Permit",
              "Health Insurance Card",
              "Tax Card"
            ],
            "description": "Jenis dokumen identitas terverifikasi yang dapat dibaca manusia. `null` sebelum verifikasi dokumen selesai, dan juga `null` setelah selesai jika kode yang diverifikasi tidak memiliki pemetaan tampilan (`SSC`, `WP`, `VISA`, `PSC`, `BC`, `OTHER`). Catatan: parameter kueri `document_type` memfilter berdasarkan kode pendek (`P`, `ID`, `DL`, `RP`, ...), bukan berdasarkan nilai tampilan ini.",
            "example": "Passport"
          },
          "full_name": {
            "type": "string",
            "nullable": true,
            "description": "Nama lengkap terbaik yang tersedia untuk sesi tersebut, diselesaikan berdasarkan urutan: OCR dokumen identitas, data hasil skrining AML, data hasil skrining validasi database, dokumen bukti alamat, kemudian detail yang diharapkan yang diberikan saat pembuatan sesi. `null` jika belum ada yang tersedia.",
            "example": "Jane Marie Doe"
          },
          "country": {
            "type": "string",
            "nullable": true,
            "description": "Negara ISO 3166-1 alpha-3 yang terkait dengan sesi, diselesaikan secara berurutan: negara penerbit dokumen ID, negara penerbit validasi database, negara penerbit bukti alamat, detail yang diharapkan, kemudian negara telepon yang terverifikasi. Mungkin berbeda dari kewarganegaraan.",
            "example": "ESP"
          },
          "status": {
            "type": "string",
            "enum": [
              "Not Started",
              "In Progress",
              "Approved",
              "Declined",
              "In Review",
              "Expired",
              "Abandoned",
              "Kyc Expired",
              "Resubmitted",
              "Awaiting User"
            ],
            "description": "Status sesi keseluruhan. Lihat halaman [Status Verifikasi](/id/integration/verification-statuses) untuk mengetahui siklus hidupnya.",
            "example": "Approved"
          },
          "vendor_data": {
            "type": "string",
            "nullable": true,
            "description": "Pengenal Anda sendiri untuk pengguna akhir, dikembalikan persis seperti yang dikirimkan saat pembuatan sesi.",
            "example": "your-user-id-123"
          },
          "didit_internal_id": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "Pengidentifikasi internal Didit untuk profil pengguna terverifikasi di balik sesi ini. Stabil di berbagai sesi dari pengguna yang sama; dapat difilter melalui parameter kueri `didit_internal_id`.",
            "example": "d9e78474-6c8d-4f2a-bb90-6f5c2f3a1147"
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "Stempel waktu UTC saat sesi dibuat.",
            "example": "2026-06-09T12:26:54.328364Z"
          },
          "features": {
            "type": "array",
            "description": "Status per fitur untuk setiap langkah verifikasi yang dikonfigurasikan dalam alur kerja sesi, sesuai urutan alur kerja.",
            "items": {
              "type": "object",
              "required": [
                "feature",
                "status"
              ],
              "properties": {
                "feature": {
                  "type": "string",
                  "enum": [
                    "ID_VERIFICATION",
                    "NFC",
                    "LIVENESS",
                    "FACE_MATCH",
                    "POA",
                    "QUESTIONNAIRE",
                    "EMAIL_VERIFICATION",
                    "PHONE",
                    "AML",
                    "IP_ANALYSIS",
                    "AGE_ESTIMATION",
                    "DATABASE_VALIDATION",
                    "GEOLOCATION"
                  ],
                  "description": "Pengenal fitur verifikasi.",
                  "example": "ID_VERIFICATION"
                },
                "status": {
                  "type": "string",
                  "enum": [
                    "Not Finished",
                    "Approved",
                    "Declined",
                    "In Review",
                    "Resub Requested"
                  ],
                  "description": "Status fitur ini. `Not Finished` hingga langkah tersebut selesai.",
                  "example": "Approved"
                }
              }
            }
          },
          "phone_number": {
            "type": "object",
            "nullable": true,
            "description": "Telepon yang terkait dengan sesi: telepon terverifikasi saat verifikasi telepon dijalankan, jika tidak, telepon kontak yang diberikan saat pembuatan sesi. Bernilai `null` jika keduanya tidak ada.",
            "required": [
              "number",
              "is_verified"
            ],
            "properties": {
              "number": {
                "type": "string",
                "description": "Nomor telepon dalam format E.164.",
                "example": "+14155552671"
              },
              "is_verified": {
                "type": "boolean",
                "description": "`true` hanya jika fitur verifikasi telepon menyetujui nomor ini.",
                "example": true
              }
            }
          },
          "email_address": {
            "type": "object",
            "nullable": true,
            "description": "Email yang terkait dengan sesi: email yang diverifikasi saat verifikasi email dijalankan, atau email kontak yang diberikan saat pembuatan sesi. `null` jika keduanya tidak ada.",
            "required": [
              "email",
              "is_verified"
            ],
            "properties": {
              "email": {
                "type": "string",
                "format": "email",
                "example": "jane@example.com"
              },
              "is_verified": {
                "type": "boolean",
                "description": "`true` hanya jika fitur verifikasi email menyetujui alamat ini.",
                "example": true
              }
            }
          },
          "additional_details": {
            "type": "object",
            "nullable": true,
            "description": "Ekstra ringkas per fitur. Hanya fitur yang menghasilkan data yang muncul sebagai kunci; `null` jika tidak ada fitur yang menghasilkan ekstra. Kolom yang dikecualikan oleh konfigurasi atribut respons alur kerja akan dihilangkan.",
            "properties": {
              "aml": {
                "type": "object",
                "description": "Hadir ketika Skrining AML dijalankan.",
                "properties": {
                  "total_hits": {
                    "type": "integer",
                    "description": "Jumlah kecocokan skrining AML.",
                    "example": 0
                  },
                  "entity_type": {
                    "type": "string",
                    "description": "Jenis entitas yang diskrining.",
                    "example": "person"
                  },
                  "is_adverse_media_fetched": {
                    "type": "boolean",
                    "example": false
                  },
                  "screened_data": {
                    "type": "object",
                    "description": "Subset dari data yang diskrining. Hanya kunci yang tidak kosong yang disertakan.",
                    "properties": {
                      "nationality": {
                        "type": "string",
                        "example": "ESP"
                      },
                      "document_number": {
                        "type": "string",
                        "example": "XX1234567"
                      },
                      "date_of_birth": {
                        "type": "string",
                        "example": "1990-05-21"
                      }
                    }
                  }
                }
              },
              "database_validation": {
                "type": "object",
                "description": "Hadir ketika Validasi Database dijalankan.",
                "properties": {
                  "validation_type": {
                    "type": "string",
                    "example": "DOCUMENT_VALIDATION"
                  },
                  "match_type": {
                    "type": "string",
                    "example": "FULL_MATCH"
                  },
                  "identification_number": {
                    "type": "string",
                    "description": "Nomor pajak, pribadi, atau dokumen yang divalidasi (pertama yang tersedia).",
                    "example": "12345678Z"
                  }
                }
              },
              "poa": {
                "type": "object",
                "description": "Hadir ketika Bukti Alamat dijalankan.",
                "properties": {
                  "document_type": {
                    "type": "string",
                    "example": "UTILITY_BILL"
                  },
                  "issuer": {
                    "type": "string",
                    "example": "Energy Co"
                  },
                  "address": {
                    "type": "string",
                    "example": "Calle Mayor 1, 28013 Madrid"
                  },
                  "name_on_document": {
                    "type": "string",
                    "example": "Jane Marie Doe"
                  }
                }
              },
              "liveness": {
                "type": "object",
                "description": "Hadir ketika Deteksi Liveness dijalankan.",
                "properties": {
                  "method": {
                    "type": "string",
                    "example": "PASSIVE"
                  },
                  "score": {
                    "type": "number",
                    "description": "Skor keyakinan liveness, dibulatkan menjadi 2 desimal.",
                    "example": 0.98
                  }
                }
              },
              "face_match": {
                "type": "object",
                "description": "Hadir ketika Pencocokan Wajah dijalankan.",
                "properties": {
                  "score": {
                    "type": "number",
                    "description": "Skor kemiripan pencocokan wajah, dibulatkan menjadi 2 desimal.",
                    "example": 0.95
                  },
                  "source_image": {
                    "type": "string",
                    "description": "URL yang memiliki masa kedaluwarsa (presigned) dari gambar wajah sumber.",
                    "example": "https://<media-host>/faces/source.jpg?X-Amz-Expires=3600&..."
                  },
                  "target_image": {
                    "type": "string",
                    "description": "URL yang memiliki masa kedaluwarsa (presigned) dari gambar wajah target.",
                    "example": "https://<media-host>/faces/target.jpg?X-Amz-Expires=3600&..."
                  }
                }
              },
              "phone_verification": {
                "type": "object",
                "description": "Hadir ketika Verifikasi Telepon dijalankan.",
                "properties": {
                  "country_code": {
                    "type": "string",
                    "description": "Negara ISO 3166-1 alpha-2 dari nomor telepon.",
                    "example": "US"
                  },
                  "is_temporary": {
                    "type": "boolean",
                    "example": false
                  },
                  "is_ported": {
                    "type": "boolean",
                    "example": false
                  },
                  "is_blocked": {
                    "type": "boolean",
                    "example": false
                  }
                }
              },
              "email_verification": {
                "type": "object",
                "description": "Hadir saat Verifikasi Email dijalankan.",
                "properties": {
                  "is_breached": {
                    "type": "boolean",
                    "example": false
                  },
                  "is_disposable": {
                    "type": "boolean",
                    "example": false
                  },
                  "is_undeliverable": {
                    "type": "boolean",
                    "example": false
                  },
                  "is_blocklisted": {
                    "type": "boolean",
                    "example": false
                  }
                }
              }
            }
          },
          "assignee": {
            "type": "object",
            "nullable": true,
            "description": "Peninjau Console yang ditugaskan ke sesi, atau `null` jika tidak ada yang memegangnya.",
            "properties": {
              "email": {
                "type": "string",
                "format": "email"
              },
              "assigned_at": {
                "type": "string",
                "format": "date-time",
                "nullable": true
              }
            }
          },
          "waiting_since": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Waktu sesi mulai menunggu peninjauan. `null` kecuali sesi berstatus `In Review`."
          },
          "sla_due_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Waktu jatuh tempo peninjauan, dari tenggat peninjauan yang ditetapkan untuk aplikasi Anda di Console. `null` kecuali sesi berstatus `In Review` dan tenggat telah ditetapkan."
          },
          "top_warnings": {
            "type": "array",
            "description": "Hingga beberapa peringatan terpenting dari sesi tersebut, untuk tampilan triase cepat. Daftar lengkap ada dalam keputusan.",
            "items": {
              "type": "object",
              "properties": {
                "risk": {
                  "type": "string",
                  "description": "Kode peringatan, misalnya `FACE_MATCH_LOW_SIMILARITY`."
                },
                "feature": {
                  "type": "string",
                  "description": "Fitur yang memicunya."
                },
                "log_type": {
                  "type": "string",
                  "nullable": true,
                  "description": "`error` atau `warning`; `null` untuk entri lama."
                },
                "short_description": {
                  "type": "string"
                }
              }
            }
          },
          "warnings_count": {
            "type": "integer",
            "description": "Jumlah peringatan pada sesi."
          }
        }
      },
      "BusinessSessionListItem": {
        "title": "KYB session row (session_kind: business)",
        "type": "object",
        "description": "Baris ringkasan untuk sesi Verifikasi Bisnis (KYB). Dikembalikan hanya jika `session_kind` bernilai `business` atau `all`.",
        "required": [
          "session_id",
          "session_kind",
          "session_number",
          "status",
          "vendor_data",
          "created_at",
          "workflow_id",
          "workflow_type",
          "workflow_label",
          "company_name",
          "registration_number",
          "country"
        ],
        "properties": {
          "session_id": {
            "type": "string",
            "format": "uuid",
            "description": "Pengenal unik sesi verifikasi bisnis.",
            "example": "8a1f63c2-1b9e-4f3a-9c41-2f6a1f0b7d52"
          },
          "session_kind": {
            "type": "string",
            "enum": [
              "business"
            ],
            "description": "Diskriminator baris. Selalu `\"business\"` untuk baris KYB.",
            "example": "business"
          },
          "session_number": {
            "type": "integer",
            "description": "Nomor urut sesi bisnis yang mudah dibaca manusia di dalam aplikasi Anda. Diberi nomor secara terpisah dari sesi KYC.",
            "example": 42
          },
          "status": {
            "type": "string",
            "enum": [
              "Not Started",
              "In Progress",
              "Approved",
              "Declined",
              "In Review",
              "Expired",
              "Abandoned",
              "Kyc Expired",
              "Resubmitted",
              "Awaiting User"
            ],
            "description": "Status sesi keseluruhan. Lihat halaman [Status Verifikasi](/id/integration/verification-statuses).",
            "example": "Approved"
          },
          "vendor_data": {
            "type": "string",
            "nullable": true,
            "description": "Pengenal Anda sendiri untuk bisnis, dikembalikan persis seperti yang dikirimkan saat pembuatan sesi.",
            "example": "your-company-id-77"
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "Stempel waktu UTC saat sesi dibuat.",
            "example": "2026-06-08T09:14:02.118450Z"
          },
          "workflow_id": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "Pengenal alur kerja yang digunakan untuk membuat sesi ini.",
            "example": "9f9b1234-aaaa-bbbb-cccc-1234567890ab"
          },
          "workflow_type": {
            "type": "string",
            "nullable": true,
            "description": "Jenis alur kerja. `kyb` untuk alur kerja bisnis.",
            "example": "kyb"
          },
          "workflow_label": {
            "type": "string",
            "nullable": true,
            "description": "Nama tampilan alur kerja.",
            "example": "Standard KYB"
          },
          "company_name": {
            "type": "string",
            "nullable": true,
            "description": "Nama perusahaan yang sedang diverifikasi, dari perusahaan di registri yang ditautkan ke sesi. Bernilai `null` hingga perusahaan dipilih.",
            "example": "Acme Holdings S.L."
          },
          "registration_number": {
            "type": "string",
            "nullable": true,
            "description": "Nomor registrasi perusahaan dari perusahaan di registri yang ditautkan ke sesi.",
            "example": "B12345678"
          },
          "country": {
            "type": "string",
            "nullable": true,
            "description": "Kode negara dari registri perusahaan yang ditautkan ke sesi.",
            "example": "ES"
          }
        }
      },
      "TransactionVerificationSessionAction": {
        "title": "Verification session",
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "verification_session"
            ]
          },
          "url": {
            "type": "string",
            "format": "uri",
            "description": "URL verifikasi yang di-hosting untuk dibuka bagi pengguna akhir."
          },
          "session_id": {
            "type": "string",
            "format": "uuid",
            "description": "ID sesi verifikasi."
          },
          "session_token": {
            "type": "string",
            "description": "Token sesi, digunakan oleh SDK seluler untuk meluncurkan alur secara native."
          },
          "status": {
            "type": "string",
            "description": "Status sesi verifikasi."
          }
        },
        "required": [
          "type",
          "url"
        ]
      },
      "TransactionWalletOwnershipAction": {
        "title": "Wallet ownership",
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "wallet_ownership"
            ]
          },
          "url": {
            "type": "string",
            "format": "uri",
            "description": "URL widget kepemilikan dompet yang di-hosting. Buka di lingkungan browser nyata - di ponsel gunakan SFSafariViewController atau Chrome Custom Tab, jangan pernah gunakan webview tersemat."
          },
          "widget_session_id": {
            "type": "string",
            "format": "uuid",
            "description": "ID sesi widget kepemilikan dompet."
          },
          "expires_at": {
            "type": "string",
            "format": "date-time",
            "description": "Kapan sesi widget kedaluwarsa."
          }
        },
        "required": [
          "type",
          "url"
        ]
      },
      "TransactionRuleActionAddScore": {
        "type": "object",
        "required": [
          "type",
          "value"
        ],
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "add_score"
            ]
          },
          "value": {
            "type": "integer",
            "description": "Poin yang ditambahkan ke skor risiko transaksi. Dapat bernilai negatif."
          }
        },
        "description": "Tambahkan poin ke skor risiko kumulatif transaksi; totalnya menentukan status melalui ambang batas peninjauan/penolakan aplikasi."
      },
      "TransactionRuleActionChangeStatus": {
        "type": "object",
        "required": [
          "type",
          "value"
        ],
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "change_status"
            ]
          },
          "value": {
            "type": "string",
            "enum": [
              "APPROVED",
              "IN_REVIEW",
              "DECLINED",
              "AWAITING_USER"
            ],
            "description": "Status yang akan langsung ditetapkan, terlepas dari skor. Kunci alias: status."
          },
          "workflow_id": {
            "type": "string",
            "format": "uuid",
            "description": "DIBUTUHKAN saat nilai adalah AWAITING_USER: alur kerja verifikasi yang diminta untuk diselesaikan oleh subjek. Kunci alias: remediation_workflow_id. Didit membuat sesi remediasi yang di-hosting untuk subjek saat aturan terpicu."
          }
        },
        "description": "Tetapkan status transaksi secara langsung. DECLINED selalu diprioritaskan di antara aturan yang cocok."
      },
      "TransactionRuleActionAddTags": {
        "type": "object",
        "required": [
          "type"
        ],
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "add_tags"
            ]
          },
          "tag_uuid": {
            "type": "string",
            "format": "uuid",
            "description": "Tag aplikasi yang ada untuk dilampirkan."
          },
          "tag_name": {
            "type": "string",
            "description": "Nama tag yang akan dilampirkan; dibuat saat pertama kali digunakan (disimpan dalam huruf besar). Berikan tag_uuid atau tag_name."
          },
          "tag_color": {
            "type": "string",
            "description": "Warna hex yang digunakan saat tag_name membuat tag baru, misalnya #007AFE."
          }
        },
        "description": "Lampirkan tag aplikasi ke transaksi yang cocok."
      },
      "TransactionRuleActionAddNote": {
        "type": "object",
        "required": [
          "type",
          "note"
        ],
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "add_note"
            ]
          },
          "note": {
            "type": "string",
            "description": "Teks catatan yang dilampirkan ke transaksi (penulis: Rule Engine). Kunci alias: nilai."
          }
        },
        "description": "Lampirkan catatan analis otomatis ke transaksi yang cocok."
      },
      "TransactionRuleActionAddToList": {
        "type": "object",
        "required": [
          "type",
          "list_id"
        ],
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "add_to_list"
            ]
          },
          "list_id": {
            "type": "string",
            "format": "uuid",
            "description": "Daftar untuk menambahkan vendor_data subjek."
          }
        },
        "description": "Tambahkan vendor_data subjek ke daftar blokir, daftar izin, atau daftar kustom."
      },
      "TransactionRuleActionOpenCase": {
        "type": "object",
        "required": [
          "type"
        ],
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "open_case"
            ]
          },
          "blueprint": {
            "type": "string",
            "format": "uuid",
            "description": "UUID blueprint kasus; default ke blueprint default aplikasi."
          },
          "grouping": {
            "type": "string",
            "enum": [
              "by_applicant",
              "by_rule_and_applicant"
            ],
            "description": "Menentukan apakah kecocokan berulang digabungkan ke dalam satu kasus per pemohon atau satu kasus per aturan+pemohon."
          },
          "attach_matched_transaction": {
            "type": "boolean",
            "description": "Lampirkan transaksi yang cocok ke kasus."
          }
        },
        "description": "Buka (atau tambahkan ke) kasus investigasi. Hanya tindakan open_case pertama pada aturan yang diterapkan."
      },
      "KYBRegistrySearchResults": {
        "type": "object",
        "properties": {
          "companies": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "kyb_response_id": {
                  "type": "string",
                  "nullable": true,
                  "description": "Handle untuk kandidat ini — teruskan ke `POST /v3/kyb/select/` untuk mengambil profil lengkap. Bersifat sementara dan hanya berlaku untuk pencarian ini: jangan menyimpannya untuk jangka panjang; cari ulang untuk mendapatkan yang baru.",
                  "example": "69aeeb95febb0f1704042259"
                },
                "name": {
                  "type": "string",
                  "nullable": true,
                  "description": "Nama perusahaan terdaftar.",
                  "example": "Tesco PLC"
                },
                "registration_number": {
                  "type": "string",
                  "nullable": true,
                  "description": "Nomor registrasi registri.",
                  "example": "00445790"
                },
                "status": {
                  "type": "string",
                  "nullable": true,
                  "description": "Status registri perusahaan yang dinormalisasi (misalnya `active`, `dissolved`, `inactive`, `struck off`).",
                  "example": "active"
                },
                "type": {
                  "type": "string",
                  "nullable": true,
                  "description": "Bentuk hukum sebagaimana dilaporkan oleh registri.",
                  "example": "Public Limited Company"
                },
                "registered_address": {
                  "type": "string",
                  "nullable": true,
                  "description": "Alamat terdaftar kandidat, saat registri mengembalikannya. Gunakan ini, bersama dengan nomor registrasi, untuk membedakan perusahaan dengan nama yang sama: di Amerika Serikat, kandidat dapat terdaftar di bawah negara bagian tempat perusahaan beroperasi alih-alih negara bagian yang Anda cari.",
                  "example": "Tesco House, Shire Park, Kestrel Way, Welwyn Garden City, AL7 1GA"
                },
                "risk_level": {
                  "type": "string",
                  "nullable": true,
                  "description": "Tingkat risiko yang dilaporkan registri, jika tersedia. Biasanya `null` pada saat pencarian."
                },
                "fetch_status": {
                  "type": "string",
                  "nullable": true,
                  "description": "Selalu `pending` untuk kandidat pencarian — profil lengkap perusahaan hanya diambil (dan ditagihkan) saat Anda memilih kandidat tersebut.",
                  "example": "pending"
                }
              }
            },
            "description": "Daftar kandidat yang telah dideduplikasi. Kosong selama `search_resolved=false` (mode webhook) atau saat tidak ada yang cocok."
          },
          "pagination": {
            "type": "object",
            "properties": {
              "total": {
                "type": "integer",
                "description": "Jumlah kandidat yang dikembalikan."
              },
              "page": {
                "type": "integer"
              },
              "per_page": {
                "type": "integer",
                "example": 25
              }
            }
          },
          "search_status": {
            "type": "string",
            "nullable": true,
            "enum": [
              "pending",
              "resolved"
            ],
            "description": "Status siklus hidup pencarian registri."
          },
          "search_resolved": {
            "type": "boolean",
            "description": "`true` setelah daftar kandidat bersifat final."
          }
        }
      },
      "KYBRegistryCandidateRequest": {
        "type": "object",
        "required": [
          "kyb_response_id"
        ],
        "properties": {
          "kyb_response_id": {
            "type": "string",
            "maxLength": 1024,
            "description": "ID kandidat dari `POST /v3/kyb/search/` (`kyb_registry.companies[].kyb_response_id`). Bersifat fana: gunakan segera setelah pencarian yang menghasilkannya. ID bisa berukuran panjang, jadi simpan dan kirim nilainya persis seperti yang dikembalikan, tanpa memotong atau mengasumsikan panjangnya.",
            "example": "69aeeb95febb0f1704042259"
          },
          "vendor_data": {
            "type": "string",
            "description": "Pengenal Anda untuk perusahaan ini; dikembalikan dan disimpan bersama sesi bisnis."
          },
          "metadata": {
            "type": "object",
            "nullable": true,
            "description": "JSON bentuk bebas yang disimpan bersama sesi bisnis dan dikembalikan dalam respons."
          },
          "save_api_request": {
            "type": "boolean",
            "default": true,
            "description": "Harus bernilai `true` (default). Pemilihan registri KYB selalu disimpan agar penagihan dan pengambilan data dapat dilacak; `false` mengembalikan `400`."
          }
        }
      },
      "WebhookEventEnvelope": {
        "type": "object",
        "description": "Kolom yang ditambahkan Didit ke setiap pengiriman webhook yang ditandatangani, apa pun jenis event-nya. Baca `webhook_type` untuk mengetahui payload mana yang Anda terima.",
        "required": [
          "event_id",
          "webhook_type",
          "timestamp",
          "created_at",
          "application_id",
          "environment"
        ],
        "properties": {
          "event_id": {
            "type": "string",
            "format": "uuid",
            "description": "Pengenal event. Setiap tujuan menerima nilai yang sama dan pengiriman ulang mempertahankannya, sehingga gunakan nilai ini untuk deduplikasi."
          },
          "webhook_type": {
            "$ref": "#/components/schemas/WebhookEvent"
          },
          "timestamp": {
            "type": "integer",
            "description": "Waktu Unix dalam detik saat pengiriman ini ditandatangani. Sama dengan header `X-Timestamp`; pengiriman ulang membawa nilai baru."
          },
          "created_at": {
            "type": "integer",
            "description": "Waktu Unix dalam detik dari perubahan yang menghasilkan event."
          },
          "application_id": {
            "type": "string",
            "format": "uuid",
            "description": "Aplikasi pemilik event tersebut."
          },
          "environment": {
            "type": "string",
            "enum": [
              "live",
              "sandbox"
            ],
            "description": "`sandbox` untuk sesi sandbox dan aplikasi sandbox, jika tidak maka `live`."
          }
        }
      },
      "SessionWebhookEventData": {
        "type": "object",
        "description": "Kolom sesi dari `status.updated` dan `data.updated`. Kolom opsional dihilangkan, tidak pernah dikirim sebagai `null`, jika tidak berlaku. Sesi bisnis (KYB) menambahkan `business_session_id`, `session_kind`, dan `vendor_business_id`.",
        "required": [
          "session_id",
          "status",
          "sandbox_scenario"
        ],
        "properties": {
          "session_id": {
            "type": "string",
            "format": "uuid",
            "description": "Sesi verifikasi."
          },
          "business_session_id": {
            "type": "string",
            "format": "uuid",
            "description": "Hanya sesi bisnis (KYB): nilai yang sama dengan `session_id`."
          },
          "session_kind": {
            "type": "string",
            "enum": [
              "business"
            ],
            "description": "Hanya sesi bisnis (KYB). Event sesi pengguna (KYC) tidak membawa `session_kind` tingkat atas; baca `decision.session_kind` sebagai gantinya."
          },
          "status": {
            "type": "string",
            "enum": [
              "Not Started",
              "In Progress",
              "Approved",
              "Declined",
              "In Review",
              "Expired",
              "Abandoned",
              "Kyc Expired",
              "Resubmitted",
              "Awaiting User"
            ],
            "description": "Status sesi setelah perubahan."
          },
          "trigger": {
            "type": "string",
            "description": "Hadir ketika event tidak dihasilkan oleh alur verifikasi itu sendiri, misalnya `manual_review`, `manual_step_update`, `ongoing_monitoring`, `webhook_reconciliation` (suatu `status.updated` yang dikirim ulang karena webhook terminal pertama tidak pernah dibuat, sehingga Anda mungkin menerima event kedua untuk keputusan yang sudah Anda dapatkan: lakukan deduplikasi pada `session_id` dan `status`), `manual_webhook_recovery`, `kyb_registry_change`, `biometric_retention` (suatu `data.updated` yang dikirim saat data biometrik live sesi dihapus sesuai jadwal) atau pengeditan `console_*` seperti `console_registry_edit`, `console_key_people_skip`, atau `console_key_people_regenerate`."
          },
          "workflow_id": {
            "type": "string",
            "format": "uuid",
            "description": "Alur kerja sesi. Ditiadakan jika sesi tidak memilikinya."
          },
          "workflow_version": {
            "type": "integer",
            "description": "Versi alur kerja yang dijalankan sesi. Dikirim bersama dengan `workflow_id`."
          },
          "vendor_data": {
            "type": "string",
            "description": "`vendor_data` Anda untuk sesi tersebut. Ditiadakan jika kosong."
          },
          "vendor_business_id": {
            "type": "string",
            "description": "Hanya sesi bisnis (KYB): bisnis yang memiliki sesi ini. Ditiadakan jika tidak ada."
          },
          "metadata": {
            "type": "object",
            "additionalProperties": true,
            "description": "`metadata` sesi Anda. Dihilangkan jika kosong."
          },
          "decision": {
            "$ref": "#/components/schemas/SessionDecision"
          },
          "resubmit_info": {
            "type": "object",
            "description": "Hanya ketika `status` bernilai `Resubmitted`: langkah-langkah yang harus diulang oleh pengguna dan alasannya.",
            "required": [
              "nodes_to_resubmit",
              "reasons"
            ],
            "properties": {
              "nodes_to_resubmit": {
                "type": "array",
                "items": {
                  "type": "object",
                  "required": [
                    "node_id",
                    "feature"
                  ],
                  "properties": {
                    "node_id": {
                      "type": "string",
                      "description": "Pengenal node seperti yang muncul dalam definisi alur kerja sesi (misalnya `feature_ocr`, `feature_liveness`).",
                      "example": "feature_poa"
                    },
                    "feature": {
                      "type": "string",
                      "description": "Tipe fitur dari node, misalnya `OCR`, `LIVENESS`, atau `PROOF_OF_ADDRESS`.",
                      "example": "PROOF_OF_ADDRESS"
                    }
                  }
                },
                "description": "Langkah alur kerja yang harus diulang oleh pengguna. Entri `{node_id, feature}` yang sama dengan `nodes_to_resubmit` di [Perbarui Status](#patch-/v3/session/-sessionId-/update-status/)."
              },
              "reasons": {
                "type": "object",
                "additionalProperties": true,
                "description": "Alasan per `node_id` di `nodes_to_resubmit`."
              }
            }
          },
          "sandbox_scenario": {
            "type": "string",
            "nullable": true,
            "description": "Hasil simulasi yang dipersiapkan pada sesi sandbox, atau `null`. Selalu `null` untuk sesi produksi."
          }
        }
      },
      "SessionStatusUpdatedEvent": {
        "description": "Sesi verifikasi telah berubah status. `decision` hanya dikirim untuk `Approved`, `Declined`, `In Review`, dan `Abandoned`; bentuknya mengikuti `GET /v3/session/{sessionId}/decision/` untuk tujuan pada webhook versi 3 (default), dan bentuk ringkas versi lama untuk tujuan versi 1 atau 2. Sesi bisnis selalu menerima keputusan bisnis versi 3.",
        "allOf": [
          {
            "$ref": "#/components/schemas/WebhookEventEnvelope"
          },
          {
            "$ref": "#/components/schemas/SessionWebhookEventData"
          },
          {
            "type": "object",
            "properties": {
              "webhook_type": {
                "type": "string",
                "enum": [
                  "status.updated"
                ],
                "description": "Selalu `status.updated`."
              }
            },
            "required": [
              "webhook_type"
            ]
          }
        ]
      },
      "SessionDataUpdatedEvent": {
        "description": "Data sesi verifikasi berubah tanpa perubahan status, misalnya setelah pengeditan peninjauan manual, penggantian langkah, atau skrining ulang pemantauan berkelanjutan. `decision` hanya dikirimkan untuk `Approved`, `Declined`, `In Review`, dan `Abandoned`; nilainya memiliki bentuk `GET /v3/session/{sessionId}/decision/` untuk tujuan webhook versi 3 (default), dan bentuk ringkas yang lebih lama untuk tujuan versi 1 atau 2. Sesi bisnis selalu menerima keputusan bisnis versi 3.",
        "allOf": [
          {
            "$ref": "#/components/schemas/WebhookEventEnvelope"
          },
          {
            "$ref": "#/components/schemas/SessionWebhookEventData"
          },
          {
            "type": "object",
            "properties": {
              "webhook_type": {
                "type": "string",
                "enum": [
                  "data.updated"
                ],
                "description": "Selalu `data.updated`."
              }
            },
            "required": [
              "webhook_type"
            ]
          }
        ]
      },
      "UserStatusUpdatedEvent": {
        "description": "Pengguna mengubah status. Tidak dikirim saat pengguna dibuat.",
        "allOf": [
          {
            "$ref": "#/components/schemas/WebhookEventEnvelope"
          },
          {
            "type": "object",
            "properties": {
              "webhook_type": {
                "type": "string",
                "enum": [
                  "user.status.updated"
                ],
                "description": "Selalu `user.status.updated`."
              },
              "vendor_user_id": {
                "type": "string",
                "format": "uuid",
                "description": "Pengguna yang menjadi subjek event."
              },
              "vendor_data": {
                "type": "string",
                "nullable": true,
                "description": "`vendor_data` Anda untuk pengguna, atau `null`."
              },
              "status": {
                "type": "string",
                "enum": [
                  "ACTIVE",
                  "IN_REVIEW",
                  "FLAGGED",
                  "BLOCKED"
                ],
                "description": "Status pengguna setelah perubahan."
              },
              "previous_status": {
                "type": "string",
                "enum": [
                  "ACTIVE",
                  "IN_REVIEW",
                  "FLAGGED",
                  "BLOCKED"
                ],
                "description": "Status sebelum perubahan."
              }
            },
            "required": [
              "webhook_type",
              "vendor_user_id",
              "vendor_data",
              "status",
              "previous_status"
            ]
          }
        ]
      },
      "UserDataUpdatedEvent": {
        "description": "Kolom pada pengguna berubah. Tidak dikirim saat pengguna dibuat. Satu penyimpanan dapat menghasilkan event status dan data sekaligus.",
        "allOf": [
          {
            "$ref": "#/components/schemas/WebhookEventEnvelope"
          },
          {
            "type": "object",
            "properties": {
              "webhook_type": {
                "type": "string",
                "enum": [
                  "user.data.updated"
                ],
                "description": "Selalu `user.data.updated`."
              },
              "vendor_user_id": {
                "type": "string",
                "format": "uuid",
                "description": "Pengguna yang menjadi subjek event."
              },
              "vendor_data": {
                "type": "string",
                "nullable": true,
                "description": "`vendor_data` Anda untuk pengguna, atau `null`."
              },
              "status": {
                "type": "string",
                "enum": [
                  "ACTIVE",
                  "IN_REVIEW",
                  "FLAGGED",
                  "BLOCKED"
                ],
                "description": "Status pengguna setelah perubahan."
              },
              "changed_fields": {
                "type": "array",
                "items": {
                  "type": "string",
                  "enum": [
                    "vendor_data",
                    "display_name",
                    "full_name",
                    "date_of_birth",
                    "metadata",
                    "portrait_image",
                    "issuing_states",
                    "approved_emails",
                    "approved_phones",
                    "features",
                    "session_count",
                    "approved_count",
                    "declined_count",
                    "in_review_count",
                    "first_session_at",
                    "last_session_at"
                  ]
                },
                "description": "Nama kolom yang berubah."
              },
              "changes": {
                "type": "object",
                "additionalProperties": {
                  "type": "object",
                  "properties": {
                    "previous": {
                      "nullable": true,
                      "description": "Nilai sebelum perubahan. Tanggal berupa string ISO 8601."
                    },
                    "current": {
                      "nullable": true,
                      "description": "Nilai setelah perubahan. Tanggal berupa string ISO 8601."
                    }
                  }
                },
                "description": "Nilai sebelumnya dan saat ini dari setiap kolom yang diubah, dipetakan berdasarkan nama kolom. Nilai dapat berupa data pribadi (nama, tanggal lahir, tautan potret, email, nomor telepon); tangani dengan semestinya."
              }
            },
            "required": [
              "webhook_type",
              "vendor_user_id",
              "vendor_data",
              "status",
              "changed_fields",
              "changes"
            ]
          }
        ]
      },
      "BusinessStatusUpdatedEvent": {
        "description": "Status bisnis berubah. Tidak dikirim saat bisnis dibuat.",
        "allOf": [
          {
            "$ref": "#/components/schemas/WebhookEventEnvelope"
          },
          {
            "type": "object",
            "properties": {
              "webhook_type": {
                "type": "string",
                "enum": [
                  "business.status.updated"
                ],
                "description": "Selalu `business.status.updated`."
              },
              "vendor_business_id": {
                "type": "string",
                "format": "uuid",
                "description": "Bisnis yang menjadi subjek event tersebut."
              },
              "vendor_data": {
                "type": "string",
                "nullable": true,
                "description": "`vendor_data` Anda untuk bisnis, atau `null`."
              },
              "status": {
                "type": "string",
                "enum": [
                  "ACTIVE",
                  "IN_REVIEW",
                  "FLAGGED",
                  "BLOCKED"
                ],
                "description": "Status bisnis setelah perubahan."
              },
              "previous_status": {
                "type": "string",
                "enum": [
                  "ACTIVE",
                  "IN_REVIEW",
                  "FLAGGED",
                  "BLOCKED"
                ],
                "description": "Status sebelum perubahan."
              }
            },
            "required": [
              "webhook_type",
              "vendor_business_id",
              "vendor_data",
              "status",
              "previous_status"
            ]
          }
        ]
      },
      "BusinessDataUpdatedEvent": {
        "description": "Kolom pada bisnis berubah. Tidak dikirim saat bisnis dibuat. Satu penyimpanan dapat menghasilkan event status dan data sekaligus.",
        "allOf": [
          {
            "$ref": "#/components/schemas/WebhookEventEnvelope"
          },
          {
            "type": "object",
            "properties": {
              "webhook_type": {
                "type": "string",
                "enum": [
                  "business.data.updated"
                ],
                "description": "Selalu `business.data.updated`."
              },
              "vendor_business_id": {
                "type": "string",
                "format": "uuid",
                "description": "Bisnis yang menjadi subjek event tersebut."
              },
              "vendor_data": {
                "type": "string",
                "nullable": true,
                "description": "`vendor_data` Anda untuk bisnis, atau `null`."
              },
              "status": {
                "type": "string",
                "enum": [
                  "ACTIVE",
                  "IN_REVIEW",
                  "FLAGGED",
                  "BLOCKED"
                ],
                "description": "Status bisnis setelah perubahan."
              },
              "changed_fields": {
                "type": "array",
                "items": {
                  "type": "string",
                  "enum": [
                    "vendor_data",
                    "display_name",
                    "metadata",
                    "legal_name",
                    "registration_number",
                    "country_code",
                    "session_count",
                    "approved_count",
                    "declined_count",
                    "in_review_count",
                    "features",
                    "first_session_at",
                    "last_session_at"
                  ]
                },
                "description": "Nama kolom yang berubah."
              },
              "changes": {
                "type": "object",
                "additionalProperties": {
                  "type": "object",
                  "properties": {
                    "previous": {
                      "nullable": true,
                      "description": "Nilai sebelum perubahan. Tanggal berupa string ISO 8601."
                    },
                    "current": {
                      "nullable": true,
                      "description": "Nilai setelah perubahan. Tanggal berupa string ISO 8601."
                    }
                  }
                },
                "description": "Nilai sebelumnya dan saat ini dari setiap kolom yang diubah, dipetakan berdasarkan nama kolom."
              }
            },
            "required": [
              "webhook_type",
              "vendor_business_id",
              "vendor_data",
              "status",
              "changed_fields",
              "changes"
            ]
          }
        ]
      },
      "TransactionCreatedEvent": {
        "description": "Transaksi dibuat dan diskrining. Hanya dikirim untuk aplikasi produksi.",
        "allOf": [
          {
            "$ref": "#/components/schemas/WebhookEventEnvelope"
          },
          {
            "type": "object",
            "properties": {
              "webhook_type": {
                "type": "string",
                "enum": [
                  "transaction.created"
                ],
                "description": "Selalu `transaction.created`."
              },
              "transaction_id": {
                "type": "string",
                "format": "uuid",
                "description": "Pengidentifikasi transaksi Didit."
              },
              "txn_id": {
                "type": "string",
                "nullable": true,
                "description": "`transaction_id` yang Anda berikan saat dibuat, atau `null`."
              },
              "status": {
                "type": "string",
                "enum": [
                  "APPROVED",
                  "IN_REVIEW",
                  "DECLINED",
                  "AWAITING_USER"
                ],
                "description": "Status pemantauan setelah perubahan."
              },
              "score": {
                "type": "integer",
                "description": "Skor risiko yang diakumulasikan oleh aturan."
              },
              "severity": {
                "type": "string",
                "nullable": true,
                "enum": [
                  "UNKNOWN",
                  "LOW",
                  "MEDIUM",
                  "HIGH",
                  "CRITICAL",
                  null
                ],
                "description": "Tingkat keparahan risiko, atau `null` sampai aturan atau penyedia menetapkannya."
              },
              "amount": {
                "type": "string",
                "description": "Jumlah transaksi sebagai string desimal. Tidak seperti API, ini tidak dinormalisasi, sehingga dapat memuat nol di akhir (hingga 18 tempat desimal)."
              },
              "currency": {
                "type": "string",
                "description": "Kode mata uang atau simbol aset kripto dari `amount`."
              },
              "direction": {
                "type": "string",
                "enum": [
                  "INBOUND",
                  "OUTBOUND"
                ],
                "description": "Arah relatif terhadap subjek."
              },
              "action_required": {
                "type": "object",
                "nullable": true,
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/TransactionVerificationSessionAction"
                  },
                  {
                    "$ref": "#/components/schemas/TransactionWalletOwnershipAction"
                  }
                ],
                "discriminator": {
                  "propertyName": "type",
                  "mapping": {
                    "verification_session": "#/components/schemas/TransactionVerificationSessionAction",
                    "wallet_ownership": "#/components/schemas/TransactionWalletOwnershipAction"
                  }
                },
                "description": "Tindakan pengguna akhir yang tertunda, atau `null`. Objek yang sama dengan `action_required` pada transaksi; `session_token` adalah kredensial, jadi jangan pernah mencatatnya dalam log."
              }
            },
            "required": [
              "webhook_type",
              "transaction_id",
              "txn_id",
              "status",
              "score",
              "severity",
              "amount",
              "currency",
              "direction",
              "action_required"
            ]
          }
        ]
      },
      "TransactionStatusUpdatedEvent": {
        "description": "Status transaksi berubah, dari aturan, peninjauan, atau tindakan pengguna akhir. Hanya dikirim untuk aplikasi produksi.",
        "allOf": [
          {
            "$ref": "#/components/schemas/WebhookEventEnvelope"
          },
          {
            "type": "object",
            "properties": {
              "webhook_type": {
                "type": "string",
                "enum": [
                  "transaction.status.updated"
                ],
                "description": "Selalu `transaction.status.updated`."
              },
              "transaction_id": {
                "type": "string",
                "format": "uuid",
                "description": "Pengidentifikasi transaksi Didit."
              },
              "txn_id": {
                "type": "string",
                "nullable": true,
                "description": "`transaction_id` yang Anda berikan saat dibuat, atau `null`."
              },
              "status": {
                "type": "string",
                "enum": [
                  "APPROVED",
                  "IN_REVIEW",
                  "DECLINED",
                  "AWAITING_USER"
                ],
                "description": "Status pemantauan setelah perubahan."
              },
              "score": {
                "type": "integer",
                "description": "Skor risiko yang diakumulasikan oleh aturan."
              },
              "severity": {
                "type": "string",
                "nullable": true,
                "enum": [
                  "UNKNOWN",
                  "LOW",
                  "MEDIUM",
                  "HIGH",
                  "CRITICAL",
                  null
                ],
                "description": "Tingkat keparahan risiko, atau `null` sampai aturan atau penyedia menetapkannya."
              },
              "amount": {
                "type": "string",
                "description": "Jumlah transaksi sebagai string desimal. Tidak seperti API, ini tidak dinormalisasi, sehingga dapat memuat nol di akhir (hingga 18 tempat desimal)."
              },
              "currency": {
                "type": "string",
                "description": "Kode mata uang atau simbol aset kripto dari `amount`."
              },
              "direction": {
                "type": "string",
                "enum": [
                  "INBOUND",
                  "OUTBOUND"
                ],
                "description": "Arah relatif terhadap subjek."
              },
              "action_required": {
                "type": "object",
                "nullable": true,
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/TransactionVerificationSessionAction"
                  },
                  {
                    "$ref": "#/components/schemas/TransactionWalletOwnershipAction"
                  }
                ],
                "discriminator": {
                  "propertyName": "type",
                  "mapping": {
                    "verification_session": "#/components/schemas/TransactionVerificationSessionAction",
                    "wallet_ownership": "#/components/schemas/TransactionWalletOwnershipAction"
                  }
                },
                "description": "Tindakan pengguna akhir yang tertunda, atau `null`. Objek yang sama dengan `action_required` pada transaksi; `session_token` adalah kredensial, jadi jangan pernah mencatatnya dalam log."
              }
            },
            "required": [
              "webhook_type",
              "transaction_id",
              "txn_id",
              "status",
              "score",
              "severity",
              "amount",
              "currency",
              "direction",
              "action_required"
            ]
          }
        ]
      },
      "TravelRuleStatusUpdatedEvent": {
        "description": "Pertukaran Travel Rule berubah status. Dikirim pada setiap transisi hingga dan termasuk `FINISHED`, `CANCELLED`, atau `EXPIRED`, tidak pernah setelahnya. Dikirim untuk aplikasi produksi dan, untuk pertukaran Travel Rule, untuk aplikasi sandbox juga (`environment: sandbox`). Tidak ada `status` tingkat atas.",
        "allOf": [
          {
            "$ref": "#/components/schemas/WebhookEventEnvelope"
          },
          {
            "type": "object",
            "properties": {
              "webhook_type": {
                "type": "string",
                "enum": [
                  "travel_rule.status.updated"
                ],
                "description": "Selalu `travel_rule.status.updated`."
              },
              "transaction_id": {
                "type": "string",
                "format": "uuid",
                "description": "Transaksi tempat pertukaran ini berada."
              },
              "txn_id": {
                "type": "string",
                "nullable": true,
                "description": "`transaction_id` yang Anda berikan saat dibuat, atau `null`."
              },
              "travel_rule_status": {
                "type": "string",
                "enum": [
                  "AWAITING_COUNTERPARTY",
                  "ON_HOLD",
                  "COMPLETED",
                  "FINISHED",
                  "CANCELLED",
                  "EXPIRED",
                  "COUNTERPARTY_MISMATCHED_DATA",
                  "COUNTERPARTY_VASP_NOT_FOUND",
                  "COUNTERPARTY_VASP_NOT_REACHABLE",
                  "UNCONFIRMED_OWNERSHIP",
                  "COUNTERPARTY_VASP_GENERAL_DECLINE",
                  "NOT_ENOUGH_COUNTERPARTY_DATA",
                  "NOT_APPLICABLE"
                ],
                "description": "Status pertukaran setelah perubahan."
              },
              "rail": {
                "type": "string",
                "enum": [
                  "",
                  "INTERNAL",
                  "TRP",
                  "GTR",
                  "TRUST",
                  "VERIFYVASP",
                  "SYGNA",
                  "EMAIL",
                  "TEST_VASP"
                ],
                "description": "Jaringan tempat bursa berjalan, atau string kosong jika tidak ada yang dapat diidentifikasi. `TEST_VASP` adalah transfer sandbox yang dijawab oleh Didit Test VASP."
              },
              "test_vasp": {
                "type": "boolean",
                "description": "Hadir dan bernilai `true` hanya pada transfer sandbox yang dijawab oleh Didit Test VASP."
              },
              "test_vasp_scenario": {
                "type": "string",
                "description": "Hadir hanya dengan `test_vasp`: skenario sandbox yang menentukan hasilnya, atau string kosong."
              },
              "direction": {
                "type": "string",
                "enum": [
                  "INBOUND",
                  "OUTBOUND"
                ],
                "description": "Arah transfer."
              }
            },
            "required": [
              "webhook_type",
              "transaction_id",
              "txn_id",
              "travel_rule_status",
              "rail",
              "direction"
            ]
          }
        ]
      },
      "WorkflowComplianceChangedEvent": {
        "description": "Status kepatuhan dari alur kerja yang dipublikasikan berubah setelah evaluasi ulang. Satu event per alur kerja. Tidak ada `status` tingkat atas.",
        "allOf": [
          {
            "$ref": "#/components/schemas/WebhookEventEnvelope"
          },
          {
            "type": "object",
            "properties": {
              "webhook_type": {
                "type": "string",
                "enum": [
                  "workflow.compliance_changed"
                ],
                "description": "Selalu `workflow.compliance_changed`."
              },
              "workflow_id": {
                "type": "string",
                "format": "uuid",
                "description": "Alur kerja yang berubah."
              },
              "workflow_version": {
                "type": "integer",
                "description": "Versi yang dievaluasi."
              },
              "workflow_label": {
                "type": "string",
                "nullable": true,
                "description": "Nama tampilan alur kerja."
              },
              "transition": {
                "type": "object",
                "required": [
                  "from",
                  "to"
                ],
                "properties": {
                  "from": {
                    "type": "string",
                    "enum": [
                      "compliant",
                      "gaps_detected",
                      "pending_change",
                      "unknown_coverage",
                      "not_evaluated"
                    ],
                    "description": "Status sebelum evaluasi ulang."
                  },
                  "to": {
                    "type": "string",
                    "enum": [
                      "compliant",
                      "gaps_detected",
                      "pending_change",
                      "unknown_coverage",
                      "not_evaluated"
                    ],
                    "description": "Status setelah evaluasi ulang."
                  }
                }
              },
              "severity": {
                "type": "string",
                "enum": [
                  "actionable",
                  "indicative",
                  "informative"
                ],
                "description": "`actionable` ketika kesenjangan terdeteksi, `indicative` untuk perubahan yang tertunda, `informative` ketika kesenjangan telah diselesaikan."
              },
              "kb_version": {
                "type": "string",
                "description": "Versi basis pengetahuan regulasi yang digunakan."
              }
            },
            "required": [
              "webhook_type",
              "workflow_id",
              "workflow_version",
              "workflow_label",
              "transition",
              "severity",
              "kb_version"
            ]
          }
        ]
      },
      "WebhookEventPayload": {
        "description": "Isi pengiriman webhook bertanda tangan, dibedakan berdasarkan `webhook_type`. `activity.created` dapat dilanggan tetapi saat ini belum dikirimkan. Perlakukan `webhook_type` lainnya sebagai tipe event baru dan simpan body mentah.",
        "oneOf": [
          {
            "$ref": "#/components/schemas/SessionStatusUpdatedEvent"
          },
          {
            "$ref": "#/components/schemas/SessionDataUpdatedEvent"
          },
          {
            "$ref": "#/components/schemas/UserStatusUpdatedEvent"
          },
          {
            "$ref": "#/components/schemas/UserDataUpdatedEvent"
          },
          {
            "$ref": "#/components/schemas/BusinessStatusUpdatedEvent"
          },
          {
            "$ref": "#/components/schemas/BusinessDataUpdatedEvent"
          },
          {
            "$ref": "#/components/schemas/TransactionCreatedEvent"
          },
          {
            "$ref": "#/components/schemas/TransactionStatusUpdatedEvent"
          },
          {
            "$ref": "#/components/schemas/TravelRuleStatusUpdatedEvent"
          },
          {
            "$ref": "#/components/schemas/WorkflowComplianceChangedEvent"
          },
          {
            "$ref": "#/components/schemas/TransactionRuleSuggestionsCreatedEvent"
          }
        ],
        "discriminator": {
          "propertyName": "webhook_type",
          "mapping": {
            "status.updated": "#/components/schemas/SessionStatusUpdatedEvent",
            "data.updated": "#/components/schemas/SessionDataUpdatedEvent",
            "user.status.updated": "#/components/schemas/UserStatusUpdatedEvent",
            "user.data.updated": "#/components/schemas/UserDataUpdatedEvent",
            "business.status.updated": "#/components/schemas/BusinessStatusUpdatedEvent",
            "business.data.updated": "#/components/schemas/BusinessDataUpdatedEvent",
            "transaction.created": "#/components/schemas/TransactionCreatedEvent",
            "transaction.status.updated": "#/components/schemas/TransactionStatusUpdatedEvent",
            "travel_rule.status.updated": "#/components/schemas/TravelRuleStatusUpdatedEvent",
            "workflow.compliance_changed": "#/components/schemas/WorkflowComplianceChangedEvent",
            "transaction_rule_suggestions.created": "#/components/schemas/TransactionRuleSuggestionsCreatedEvent"
          }
        }
      },
      "KYBRegistrySearchResolvedCallback": {
        "type": "object",
        "description": "Isi callback yang dikirim ke `webhook_url` pada `POST /v3/kyb/search/` setelah pencarian registri selesai. Callback ini tidak ditandatangani: permintaan membawa `X-Didit-Unsigned-Callback: true` dan tidak menyertakan header tanda tangan apa pun, jadi konfirmasikan dengan mencocokkan `request_id` terhadap pencarian yang Anda mulai. Menggunakan `event_type`, bukan `webhook_type`.",
        "required": [
          "event_id",
          "event_type",
          "request_id",
          "vendor_data",
          "metadata",
          "search_status",
          "search_resolved",
          "kyb_registry",
          "timestamp",
          "created_at"
        ],
        "properties": {
          "event_id": {
            "type": "string",
            "format": "uuid",
            "description": "Pengenal callback."
          },
          "event_type": {
            "type": "string",
            "enum": [
              "kyb.registry_search.resolved"
            ],
            "description": "Selalu `kyb.registry_search.resolved`."
          },
          "request_id": {
            "type": "string",
            "format": "uuid",
            "description": "`request_id` yang dikembalikan oleh `POST /v3/kyb/search/`."
          },
          "vendor_data": {
            "type": "string",
            "nullable": true,
            "description": "Menampilkan kembali `vendor_data` yang Anda kirimkan."
          },
          "metadata": {
            "type": "object",
            "nullable": true,
            "additionalProperties": true,
            "description": "Salinan `metadata` yang Anda kirimkan."
          },
          "search_status": {
            "type": "string",
            "description": "Selalu `resolved` saat ini."
          },
          "search_resolved": {
            "type": "boolean",
            "description": "`true` jika `search_status` bernilai `resolved`."
          },
          "kyb_registry": {
            "$ref": "#/components/schemas/KYBRegistrySearchResults"
          },
          "timestamp": {
            "type": "integer",
            "description": "Waktu Unix dalam detik saat callback dimasukkan ke dalam antrean."
          },
          "created_at": {
            "type": "integer",
            "description": "Waktu Unix dalam detik saat callback dimasukkan ke dalam antrean."
          }
        }
      },
      "AMLScreening": {
        "type": "object",
        "properties": {
          "node_id": {
            "type": "string",
            "description": "Pengenal unik untuk langkah AML ini di graf alur kerja."
          },
          "status": {
            "type": "string",
            "description": "Status tingkat fitur dari skrining AML ini. Tidak bergantung pada `status` sesi tingkat atas — sesi dapat mencapai keputusan keseluruhannya sementara fitur individual tetap `In Review`.",
            "enum": [
              "Not Finished",
              "Approved",
              "Declined",
              "In Review",
              "Resub Requested"
            ]
          },
          "total_hits": {
            "type": "integer",
            "description": "Jumlah total kecocokan yang ditemukan"
          },
          "entity_type": {
            "type": "string",
            "description": "Jenis entitas yang diskrining: orang atau perusahaan"
          },
          "hits": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string",
                  "description": "Pengenal stabil dari Didit untuk hit: `hit_` yang diikuti oleh 24 karakter heksadesimal. Entitas cocok yang sama mempertahankan `id` yang sama saat subjek menjalani skrining ulang. Teruskan ini sebagai `hit_id` ke endpoint peninjauan hit AML."
                },
                "url": {
                  "type": "string",
                  "format": "uri",
                  "description": "URL sumber untuk kecocokan"
                },
                "match": {
                  "type": "boolean",
                  "description": "Apakah ini merupakan kecocokan yang dikonfirmasi"
                },
                "score": {
                  "type": "number",
                  "format": "float",
                  "nullable": true,
                  "minimum": 0,
                  "maximum": 1,
                  "description": "Skor kecocokan berbobot yang sudah usang dalam rentang 0-1 (misalnya `0.73`). Gunakan `match_score` (0-100) sebagai gantinya.",
                  "deprecated": true
                },
                "target": {
                  "type": "boolean",
                  "nullable": true,
                  "description": "Apakah entitas yang cocok adalah target langsung dalam daftar (berkebalikan dengan pihak terkait). `null` jika sumber tidak menentukannya."
                },
                "caption": {
                  "type": "string",
                  "description": "Keterangan atau judul kecocokan"
                },
                "datasets": {
                  "type": "array",
                  "items": {
                    "type": "string",
                    "enum": [
                      "PEP",
                      "PEP Level 1",
                      "PEP Level 2",
                      "PEP Level 3",
                      "PEP Level 4",
                      "Sanctions",
                      "Adverse Media",
                      "Warnings and Regulatory Enforcement",
                      "Fitness and Probity",
                      "SIP",
                      "SIE",
                      "Insolvency",
                      "Other Lists"
                    ]
                  },
                  "description": "Daftar kategori himpunan data tempat kecocokan ditemukan. Menunjukkan apakah entitas muncul dalam daftar PEP (dengan tingkat), database sanksi, media negatif, peringatan/penegakan regulasi, atau himpunan data kepatuhan lainnya. `Other Lists` jika sumber entitas tidak menyebutkan salah satu dari kategori ini."
                },
                "features": {
                  "type": "object",
                  "nullable": true,
                  "description": "Fitur tambahan dari kecocokan"
                },
                "rca_name": {
                  "type": "string",
                  "description": "Nama RCA jika berlaku"
                },
                "last_seen": {
                  "type": "string",
                  "format": "date-time",
                  "description": "Tanggal saat kecocokan terakhir terlihat"
                },
                "risk_view": {
                  "type": "object",
                  "properties": {
                    "crimes": {
                      "type": "object",
                      "properties": {
                        "score": {
                          "type": "integer"
                        },
                        "weightage": {
                          "type": "integer"
                        },
                        "risk_level": {
                          "type": "string"
                        },
                        "risk_scores": {
                          "type": "object"
                        }
                      }
                    },
                    "countries": {
                      "type": "object",
                      "properties": {
                        "score": {
                          "type": "integer"
                        },
                        "weightage": {
                          "type": "integer"
                        },
                        "risk_level": {
                          "type": "string"
                        },
                        "risk_scores": {
                          "type": "object"
                        }
                      }
                    },
                    "categories": {
                      "type": "object",
                      "properties": {
                        "score": {
                          "type": "integer"
                        },
                        "weightage": {
                          "type": "integer"
                        },
                        "risk_level": {
                          "type": "string"
                        },
                        "risk_scores": {
                          "type": "object"
                        }
                      }
                    },
                    "custom_list": {
                      "type": "object"
                    }
                  }
                },
                "first_seen": {
                  "type": "string",
                  "format": "date-time",
                  "description": "Tanggal saat kecocokan pertama kali terlihat"
                },
                "properties": {
                  "type": "object",
                  "properties": {
                    "name": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "alias": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "notes": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "title": {
                      "type": "string",
                      "nullable": true
                    },
                    "gender": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "height": {
                      "type": "string",
                      "nullable": true
                    },
                    "topics": {
                      "type": "string",
                      "nullable": true
                    },
                    "weight": {
                      "type": "string",
                      "nullable": true
                    },
                    "address": {
                      "type": "string",
                      "nullable": true
                    },
                    "country": {
                      "type": "string",
                      "nullable": true
                    },
                    "website": {
                      "type": "string",
                      "nullable": true
                    },
                    "eyeColor": {
                      "type": "string",
                      "nullable": true
                    },
                    "keywords": {
                      "type": "string",
                      "nullable": true
                    },
                    "lastName": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "position": {
                      "type": "string",
                      "nullable": true
                    },
                    "religion": {
                      "type": "string",
                      "nullable": true
                    },
                    "birthDate": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "education": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "ethnicity": {
                      "type": "string",
                      "nullable": true
                    },
                    "firstName": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "hairColor": {
                      "type": "string",
                      "nullable": true
                    },
                    "weakAlias": {
                      "type": "string",
                      "nullable": true
                    },
                    "birthPlace": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "modifiedAt": {
                      "type": "string",
                      "nullable": true
                    },
                    "wikidataId": {
                      "type": "string",
                      "nullable": true
                    },
                    "citizenship": {
                      "type": "string",
                      "nullable": true
                    },
                    "nationality": {
                      "type": "string",
                      "nullable": true
                    }
                  }
                },
                "match_score": {
                  "type": "number",
                  "description": "Skor keyakinan identitas berbobot (0-100) yang dihitung dari kemiripan nama, tanggal lahir, dan pencocokan negara. Digunakan untuk menentukan apakah kecocokan merupakan Positif Palsu atau Kemungkinan Cocok.",
                  "format": "float",
                  "nullable": true
                },
                "risk_score": {
                  "type": "number",
                  "description": "Skor risiko entitas (0-100). Digunakan untuk menentukan status AML akhir (Approved/In Review/Declined) berdasarkan risk_score tertinggi di antara kecocokan yang bukan positif palsu."
                },
                "review_status": {
                  "type": "string",
                  "description": "Status peninjauan untuk hasil pencocokan ini. Dapat berupa 'Unreviewed', 'Confirmed Match', 'False Positive', atau 'Inconclusive'.",
                  "enum": [
                    "Unreviewed",
                    "Confirmed Match",
                    "False Positive",
                    "Inconclusive"
                  ]
                },
                "score_breakdown": {
                  "type": "object",
                  "description": "Rincian mendetail tentang bagaimana match_score dihitung.",
                  "properties": {
                    "name_score": {
                      "type": "integer",
                      "description": "Persentase kemiripan nama mentah (0-100)."
                    },
                    "name_weight": {
                      "type": "integer",
                      "description": "Bobot asli untuk nama dari konfigurasi (0-100)."
                    },
                    "name_weight_normalized": {
                      "type": "number",
                      "description": "Bobot yang dinormalisasi untuk nama setelah pembobotan ulang untuk data yang hilang (0-100)."
                    },
                    "name_contribution": {
                      "type": "number",
                      "description": "Poin yang dikontribusikan oleh nama ke skor total."
                    },
                    "dob_score": {
                      "type": "integer",
                      "description": "Skor kecocokan DOB (-100 hingga 100)."
                    },
                    "dob_weight": {
                      "type": "integer",
                      "description": "Bobot asli untuk tanggal lahir dari konfigurasi (0-100)."
                    },
                    "dob_weight_normalized": {
                      "type": "number",
                      "description": "Bobot yang dinormalisasi untuk DOB setelah pembobotan ulang untuk data yang hilang (0-100)."
                    },
                    "dob_contribution": {
                      "type": "number",
                      "description": "Poin yang dikontribusikan oleh tanggal lahir ke skor total."
                    },
                    "country_score": {
                      "type": "integer",
                      "description": "Skor kecocokan negara (-100 hingga 100)."
                    },
                    "country_weight": {
                      "type": "integer",
                      "description": "Bobot asli untuk negara dari konfigurasi (0-100)."
                    },
                    "country_weight_normalized": {
                      "type": "number",
                      "description": "Bobot yang dinormalisasi untuk negara setelah pembobotan ulang untuk data yang hilang (0-100)."
                    },
                    "country_contribution": {
                      "type": "number",
                      "description": "Poin yang dikontribusikan oleh negara ke skor total."
                    },
                    "document_number_match_type": {
                      "type": "string",
                      "description": "Hasil evaluasi 'Golden Key' untuk nomor dokumen.",
                      "enum": [
                        "MATCH",
                        "NEUTRAL",
                        "HARD_MISMATCH"
                      ]
                    },
                    "document_number_effect": {
                      "type": "string",
                      "description": "Deskripsi yang mudah dibaca manusia mengenai pengaruh nomor dokumen terhadap skor."
                    },
                    "total_score": {
                      "type": "integer",
                      "description": "Skor kecocokan berbobot akhir (0-100)."
                    }
                  }
                },
                "pep_matches": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "aliases": {
                        "type": "array",
                        "items": {
                          "type": "string"
                        }
                      },
                      "education": {
                        "type": "array",
                        "items": {
                          "type": "string"
                        }
                      },
                      "list_name": {
                        "type": "string"
                      },
                      "publisher": {
                        "type": "string"
                      },
                      "source_url": {
                        "type": "string",
                        "format": "uri"
                      },
                      "description": {
                        "type": "string"
                      },
                      "matched_name": {
                        "type": "string"
                      },
                      "pep_position": {
                        "type": "string"
                      },
                      "date_of_birth": {
                        "type": "string"
                      },
                      "other_sources": {
                        "type": "array",
                        "items": {
                          "type": "string"
                        }
                      },
                      "place_of_birth": {
                        "type": "string"
                      }
                    }
                  }
                },
                "linked_entities": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "name": {
                        "type": "array",
                        "items": {
                          "type": "string"
                        }
                      },
                      "active": {
                        "type": "array",
                        "items": {
                          "type": "string"
                        }
                      },
                      "status": {
                        "type": "array",
                        "items": {
                          "type": "string"
                        }
                      },
                      "details": {
                        "type": "array",
                        "items": {
                          "type": "string"
                        }
                      },
                      "relation": {
                        "type": "array",
                        "items": {
                          "type": "string"
                        }
                      }
                    }
                  }
                },
                "warning_matches": {
                  "type": "array",
                  "description": "Daftar kecocokan peringatan dan penegakan regulasi. Termasuk entri dari kategori: Warning, SIP, Warnings and Regulatory Enforcement, Fitness and Probity, SIE, dan Insolvency.",
                  "items": {
                    "type": "object",
                    "properties": {
                      "list_name": {
                        "type": "string",
                        "description": "Nama penerbit daftar peringatan"
                      },
                      "matched_name": {
                        "type": "string",
                        "description": "Nama yang cocok dengan daftar peringatan"
                      },
                      "description": {
                        "type": "string",
                        "description": "Deskripsi entri peringatan"
                      },
                      "publisher": {
                        "type": "string",
                        "description": "Penerbit atau sumber peringatan"
                      },
                      "source_url": {
                        "type": "string",
                        "format": "uri",
                        "description": "URL sumber peringatan"
                      },
                      "other_sources": {
                        "type": "array",
                        "items": {
                          "type": "string"
                        },
                        "description": "URL sumber tambahan"
                      },
                      "countries": {
                        "type": "array",
                        "items": {
                          "type": "string"
                        },
                        "nullable": true,
                        "description": "Negara yang terkait dengan peringatan"
                      },
                      "created_at": {
                        "type": "string",
                        "nullable": true,
                        "description": "Tanggal entri peringatan dibuat"
                      },
                      "updated_at": {
                        "type": "string",
                        "nullable": true,
                        "description": "Tanggal entri peringatan terakhir diperbarui"
                      },
                      "additional_data": {
                        "type": "object",
                        "description": "Data tambahan dari sumber peringatan. Dapat berisi objek `data` dengan array `case_details`.",
                        "properties": {
                          "data": {
                            "type": "object",
                            "properties": {
                              "case_details": {
                                "type": "array",
                                "description": "Rincian kasus peringatan yang terkait dengan kecocokan ini",
                                "items": {
                                  "type": "object",
                                  "properties": {
                                    "case_type": {
                                      "type": "string",
                                      "description": "Jenis kasus peringatan",
                                      "enum": [
                                        "Accusation",
                                        "Arrest",
                                        "Bribery",
                                        "Criminal",
                                        "Fraud",
                                        "Illegal Fundraising",
                                        "Non-conviction Terror",
                                        "Proclaimed Offender",
                                        "Regulatory Enforcement",
                                        "Terrorism",
                                        "Terrorism-related",
                                        "Terrorism-related listing"
                                      ]
                                    }
                                  }
                                }
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                },
                "sanction_matches": {
                  "type": "array",
                  "description": "Daftar kecocokan daftar sanksi yang ditemukan untuk entitas ini.",
                  "items": {
                    "type": "object",
                    "properties": {
                      "list_name": {
                        "type": "array",
                        "items": {
                          "type": "string"
                        },
                        "nullable": true,
                        "description": "Nama daftar sanksi"
                      },
                      "matched_name": {
                        "type": "string",
                        "description": "Nama yang cocok dengan daftar sanksi"
                      },
                      "description": {
                        "type": "string",
                        "description": "Deskripsi entri sanksi"
                      },
                      "reason": {
                        "type": "string",
                        "nullable": true,
                        "description": "Alasan teks bebas mengapa entitas tersebut dikenai sanksi. Digabungkan dari entri alasan daftar sanksi. Contoh: 'Executive Order 13224 (Terrorism)', 'Support for actions undermining Ukraine's sovereignty', 'Listed due to national security concerns.'"
                      },
                      "source_url": {
                        "type": "string",
                        "format": "uri",
                        "description": "URL sumber sanksi"
                      },
                      "other_sources": {
                        "type": "array",
                        "items": {
                          "type": "string"
                        },
                        "description": "URL sumber tambahan"
                      },
                      "details": {
                        "type": "array",
                        "items": {
                          "type": "string"
                        },
                        "description": "Detail tambahan tentang sanksi"
                      },
                      "legal_basis": {
                        "type": "array",
                        "items": {
                          "type": "string"
                        },
                        "description": "Dasar hukum untuk sanksi"
                      },
                      "listed_on": {
                        "type": "array",
                        "items": {
                          "type": "string"
                        },
                        "nullable": true,
                        "description": "Tanggal entitas dimasukkan ke dalam daftar"
                      },
                      "sanction_list": {
                        "type": "array",
                        "items": {
                          "type": "string"
                        },
                        "nullable": true,
                        "description": "Pengidentifikasi daftar sanksi"
                      },
                      "sanction_program": {
                        "type": "array",
                        "items": {
                          "type": "string"
                        },
                        "description": "Program sanksi yang mencantumkan entitas"
                      },
                      "sanctioning_authority": {
                        "type": "array",
                        "items": {
                          "type": "string"
                        },
                        "description": "Otoritas yang memberlakukan sanksi"
                      },
                      "updated_on": {
                        "type": "array",
                        "items": {
                          "type": "string"
                        },
                        "description": "Tanggal saat entri sanksi terakhir diperbarui"
                      },
                      "additional_data": {
                        "type": "object",
                        "description": "Data tambahan dari sumber sanksi yang tidak tercakup dalam kolom utama"
                      }
                    }
                  }
                },
                "adverse_media_details": {
                  "type": "object",
                  "properties": {
                    "sentiment": {
                      "type": "string"
                    },
                    "entity_type": {
                      "type": "string"
                    },
                    "sentiment_score": {
                      "type": "integer"
                    },
                    "adverse_keywords": {
                      "type": "object",
                      "additionalProperties": {
                        "type": "integer"
                      }
                    }
                  }
                },
                "adverse_media_matches": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "country": {
                        "type": "string"
                      },
                      "summary": {
                        "type": "string"
                      },
                      "headline": {
                        "type": "string"
                      },
                      "sentiment": {
                        "type": "string"
                      },
                      "thumbnail": {
                        "type": "string",
                        "format": "uri"
                      },
                      "source_url": {
                        "type": "string",
                        "format": "uri"
                      },
                      "author_name": {
                        "type": "string",
                        "nullable": true
                      },
                      "other_sources": {
                        "type": "array",
                        "items": {
                          "type": "string"
                        }
                      },
                      "adverse_keywords": {
                        "type": "array",
                        "items": {
                          "type": "string"
                        }
                      },
                      "sentiment_score": {
                        "type": "integer"
                      },
                      "publication_date": {
                        "type": "string",
                        "format": "date-time"
                      }
                    }
                  }
                },
                "additional_information": {
                  "type": "object"
                }
              }
            }
          },
          "score": {
            "type": "number",
            "format": "float",
            "nullable": true,
            "minimum": 0,
            "maximum": 100,
            "description": "Skor skrining AML keseluruhan — skor risiko tertinggi di semua hit (float, 0-100). `null` hingga dihitung."
          },
          "screened_data": {
            "type": "object",
            "properties": {
              "full_name": {
                "type": "string"
              },
              "nationality": {
                "type": "string"
              },
              "date_of_birth": {
                "type": "string",
                "format": "date"
              },
              "document_number": {
                "type": "string",
                "nullable": true
              }
            }
          },
          "is_ongoing_monitoring_enabled": {
            "type": "boolean",
            "description": "Menentukan apakah Pemantauan AML Berkelanjutan diaktifkan untuk skrining ini. Jika `true`, entitas diskrining ulang secara berkala dan setiap kecocokan baru akan memperbarui laporan."
          },
          "next_ongoing_monitoring_bill_date": {
            "type": "string",
            "format": "date",
            "nullable": true,
            "description": "Tanggal (YYYY-MM-DD) saat langganan pemantauan berkelanjutan ini akan ditagih berikutnya. Dihitung sebagai tanggal penagihan pemantauan berkelanjutan terakhir ditambah 365 hari ketika `is_ongoing_monitoring_enabled = true`; jika tidak, bernilai `null`. Ini adalah tanggal penagihan, bukan tanggal skrining - gunakan `last_ongoing_screening_at` untuk itu."
          },
          "last_ongoing_screening_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Waktu ketika pemantauan berkelanjutan terakhir kali menyelesaikan skrining ulang terhadap rekaman ini, terlepas dari apakah hasilnya berubah atau tidak. `null` jika rekaman belum pernah diskrining ulang; nilai ini tidak pernah diisi surut dari tanggal pengaktifan atau penagihan."
          },
          "last_ongoing_screening_datasets_updated_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Tanggal pembaruan himpunan data AML terbaru yang dilaporkan penyedia pada saat skrining tersebut. `null` jika penyedia tidak melaporkan tanggal himpunan data; tidak pernah diperkirakan."
          },
          "warnings": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "feature": {
                  "type": "string",
                  "enum": [
                    "ID_VERIFICATION",
                    "NFC",
                    "LIVENESS",
                    "FACEMATCH",
                    "PROOF_OF_ADDRESS",
                    "PHONE",
                    "EMAIL",
                    "AML",
                    "LOCATION",
                    "DATABASE_VALIDATION",
                    "QUESTIONNAIRE",
                    "DOCUMENT_AI",
                    "KYB_REGISTRY",
                    "KYB_DOCUMENTS",
                    "KYB_KEY_PEOPLE",
                    "GEOLOCATION",
                    "SIGNATURE"
                  ],
                  "description": "Fitur yang menghasilkan peringatan ini. Nilai ini mengidentifikasi blok fitur tempat peringatan tersebut berada. Dalam Skrining AML, nilai ini biasanya `AML`, tetapi enum di atas bersifat otoritatif di semua peringatan fitur pada payload keputusan."
                },
                "risk": {
                  "type": "string"
                },
                "additional_data": {
                  "type": "object",
                  "nullable": true
                },
                "log_type": {
                  "type": "string"
                },
                "short_description": {
                  "type": "string"
                },
                "long_description": {
                  "type": "string"
                },
                "node_id": {
                  "type": "string",
                  "description": "ID node graf alur kerja yang menghasilkan peringatan ini"
                }
              }
            }
          }
        }
      },
      "MonitoringEvent": {
        "type": "object",
        "description": "Satu event pemantauan tersimpan sebagaimana dikembalikan oleh endpoint daftar dan linimasa subjek. Bukti terbatas (payload, konteks perangkat, bukti aturan) hanya dikembalikan oleh `GET /v3/events/{event_uuid}/`.",
        "required": [
          "event_uuid",
          "event_id",
          "event_category",
          "action_type",
          "occurred_at",
          "received_at",
          "status",
          "score",
          "subject_vendor_data",
          "subject_entity_type",
          "subject_uuid",
          "counterparty_vendor_data",
          "session_id",
          "device_fingerprint",
          "ip_address",
          "ip_country",
          "amount",
          "currency",
          "game_id",
          "round_id",
          "bonus_id",
          "affiliate_code",
          "payment_reference_id",
          "retention_class",
          "rules_matched_count",
          "correlation_pending",
          "is_droppable"
        ],
        "properties": {
          "event_uuid": {
            "type": "string",
            "format": "uuid",
            "description": "Pengidentifikasi Didit untuk event tersebut. Gunakan sebagai `{event_uuid}` dalam panggilan pengambilan dan penghapusan."
          },
          "event_id": {
            "type": "string",
            "maxLength": 128,
            "description": "Pengenal Anda sendiri, kunci idempotensi yang Anda kirimkan."
          },
          "event_category": {
            "type": "string",
            "enum": [
              "auth",
              "session",
              "gameplay",
              "bonus",
              "affiliate",
              "payment",
              "dispute",
              "security",
              "responsible_gambling",
              "custom"
            ],
            "description": "Kategori peristiwa."
          },
          "action_type": {
            "type": "string",
            "maxLength": 128,
            "description": "Hal yang terjadi dalam kategori, sesuai yang Anda kirimkan."
          },
          "occurred_at": {
            "type": "string",
            "format": "date-time",
            "description": "Waktu ketika peristiwa terjadi di pihak Anda."
          },
          "received_at": {
            "type": "string",
            "format": "date-time",
            "description": "Waktu ketika Didit menerima event tersebut."
          },
          "status": {
            "type": "string",
            "enum": [
              "ACCEPTED",
              "APPROVED",
              "IN_REVIEW",
              "DECLINED"
            ],
            "description": "`ACCEPTED`: disimpan, tidak ada aturan yang cocok yang mengubah statusnya (jawaban normal untuk sebagian besar peristiwa, dan selalu menjadi jawaban dalam aplikasi sandbox, tempat aturan tidak dijalankan). `APPROVED`: aturan cocok dan skor tetap di bawah ambang batas peninjauan Anda. `IN_REVIEW`: aturan menaikkan skor melampaui ambang batas peninjauan atau menetapkan status tersebut. `DECLINED`: aturan menolaknya atau skor melampaui ambang batas penolakan Anda."
          },
          "score": {
            "type": "integer",
            "description": "Skor aturan yang terakumulasi. Dimulai dari 0; tindakan aturan `add_score` mengubahnya (selisih negatif diizinkan)."
          },
          "subject_vendor_data": {
            "type": "string",
            "maxLength": 255,
            "description": "`subject.vendor_data` dari event: id Anda untuk pengguna atau perusahaan."
          },
          "subject_entity_type": {
            "type": "string",
            "description": "`individual` atau `company`: jenis subjek yang disebut oleh `subject_vendor_data`.",
            "example": "individual"
          },
          "subject_uuid": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "UUID pengguna (individu) atau perusahaan yang menjadi hasil resolusi peristiwa, atau null jika rekaman tersebut sudah tidak ada."
          },
          "counterparty_vendor_data": {
            "type": "string",
            "nullable": true,
            "description": "Pihak lain dalam peristiwa P2P (dipromosikan dari `payload.counterparty_vendor_data`).",
            "maxLength": 255
          },
          "session_id": {
            "type": "string",
            "nullable": true,
            "description": "`session.session_id` dikirim bersama event.",
            "maxLength": 255
          },
          "device_fingerprint": {
            "type": "string",
            "nullable": true,
            "description": "`device_context.fingerprint` dikirim bersama peristiwa.",
            "maxLength": 255
          },
          "ip_address": {
            "type": "string",
            "nullable": true,
            "description": "Alamat IP peristiwa. Pada jalur server ini adalah `device_context.network_context.ip_address` seperti yang Anda kirimkan; pada jalur perangkat ini adalah IP permintaan.",
            "maxLength": 64
          },
          "ip_country": {
            "type": "string",
            "nullable": true,
            "description": "Kode negara dari `ip_address` hasil pengayaan IP, atau null jika alamat tidak diperkaya (hilang, privat, atau telemetri bernilai rendah yang alamatnya belum diketahui).",
            "example": "ES"
          },
          "amount": {
            "type": "string",
            "nullable": true,
            "description": "Jumlah sebagai string desimal dengan 18 tempat desimal, dari `transaction_context.amount`, `payload.amount` atau `payload.stake_amount`, sesuai urutan tersebut.",
            "example": "250.000000000000000000"
          },
          "currency": {
            "type": "string",
            "nullable": true,
            "description": "Mata uang dari `transaction_context.currency` atau `payload.currency`.",
            "maxLength": 10
          },
          "game_id": {
            "type": "string",
            "nullable": true,
            "description": "Dipromosikan dari `payload.game_id`.",
            "maxLength": 128
          },
          "round_id": {
            "type": "string",
            "nullable": true,
            "description": "Dipromosikan dari `payload.round_id`.",
            "maxLength": 128
          },
          "bonus_id": {
            "type": "string",
            "nullable": true,
            "description": "Dipromosikan dari `payload.bonus_id`.",
            "maxLength": 128
          },
          "affiliate_code": {
            "type": "string",
            "nullable": true,
            "description": "Dipromosikan dari `payload.affiliate_code`.",
            "maxLength": 128
          },
          "payment_reference_id": {
            "type": "string",
            "nullable": true,
            "description": "Referensi pembayaran dari `transaction_context.payment_reference_id` atau `payload.payment_reference_id`.",
            "maxLength": 255
          },
          "retention_class": {
            "type": "string",
            "enum": [
              "low_value",
              "standard",
              "risk_relevant",
              "monetary_or_compliance"
            ],
            "description": "Kelas retensi. Event pembayaran dan sengketa adalah `monetary_or_compliance`; event keamanan dan perjudian yang bertanggung jawab adalah `risk_relevant`; `session.page_view`, `session.sdk_heartbeat`, `session.sdk_loaded`, `session.device_seen`, `session.bot_signal_observed`, `bonus.promotion_viewed` dan `affiliate.referral_clicked` adalah `low_value`; selebihnya adalah `standard`. Event yang cocok dengan aturan aktif dipromosikan ke `risk_relevant` (tidak pernah diturunkan)."
          },
          "rules_matched_count": {
            "type": "integer",
            "minimum": 0,
            "description": "Jumlah aturan yang cocok dengan peristiwa, termasuk aturan dalam mode `TEST` (yang mencatat bukti tetapi tidak menerapkan tindakan apa pun)."
          },
          "correlation_pending": {
            "type": "boolean",
            "description": "`true` selama aturan asinkron (korelasi lintas subjek, atau urutan lebih dari 24 jam) masih harus berjalan untuk event ini. Ini akan terselesaikan dalam beberapa menit dan `status`, `score`, serta `rules_matched_count` akan diperbarui langsung di tempat."
          },
          "is_droppable": {
            "type": "boolean",
            "description": "Menentukan apakah SDK yang mengalami backpressure boleh mengabaikan event jenis ini. Bernilai `false` untuk setiap event `security`, `payment`, `dispute`, dan `responsible_gambling`, serta untuk `gameplay.bet_placed`, `gameplay.bet_settled`, dan `gameplay.p2p_settlement`."
          }
        }
      },
      "MonitoringEventDetail": {
        "description": "Satu event pemantauan dengan envelope lengkap, pengayaan, dan bukti aturan. Setiap kolom dari `MonitoringEvent` ditambah kolom-kolom di bawah ini.",
        "allOf": [
          {
            "$ref": "#/components/schemas/MonitoringEvent"
          },
          {
            "type": "object",
            "required": [
              "payload",
              "custom_values",
              "device_context",
              "field_sources",
              "session_sequence",
              "table_id",
              "hand_id",
              "match_id",
              "market_id",
              "side",
              "role",
              "net_result_amount",
              "payment_fingerprint",
              "instrument_reference_hash",
              "withdrawal_address_hash",
              "dispute_id",
              "chargeback_id",
              "changed_field",
              "identity_match_ref",
              "schema_version",
              "expires_at",
              "rules_evaluated_count",
              "rule_runs",
              "ip_enrichment",
              "subject_profile",
              "tags"
            ],
            "properties": {
              "payload": {
                "type": "object",
                "additionalProperties": true,
                "description": "Kolom kategori yang Anda kirimkan dalam `payload`."
              },
              "custom_values": {
                "type": "object",
                "additionalProperties": true,
                "description": "Nilai skalar `custom_values` yang Anda kirim. Didit menambahkan `vpn_or_proxy_detected: true` atau `is_data_center: true` saat pengayaan IP menandai alamat tersebut dan Anda tidak mengaturnya."
              },
              "device_context": {
                "type": "object",
                "additionalProperties": true,
                "description": "Konteks perangkat sebagaimana disimpan: `device_context` Anda (termasuk `fingerprint`, `persistent_device_id`, dan `bot_score` saat dikirim) dengan `network_context` yang dilengkapi oleh pengayaan IP (`ip_country`, `ip_country_code`, `ip_city`, `asn_number`, `asn_organization`, `is_vpn_or_tor`, `is_data_center`, `proxy_type`, `connection_type`) untuk kunci yang Anda biarkan kosong."
              },
              "field_sources": {
                "type": "object",
                "additionalProperties": {
                  "type": "string",
                  "enum": [
                    "customer",
                    "sdk",
                    "server"
                  ]
                },
                "description": "Jalur kolom ke asal-usul (provenance): `customer` (dikirim oleh backend Anda), `sdk` (dikirim melalui jalur perangkat), atau `server` (diturunkan oleh Didit, seperti `received_at` dan kolom jaringan yang diperkaya). Periksa ini sebelum menindaklanjuti kecocokan."
              },
              "session_sequence": {
                "type": "integer",
                "format": "int64",
                "nullable": true,
                "description": "`session.sequence` dikirim bersama event."
              },
              "table_id": {
                "type": "string",
                "nullable": true,
                "description": "Dipromosikan dari `payload.table_id`.",
                "maxLength": 128
              },
              "hand_id": {
                "type": "string",
                "nullable": true,
                "description": "Dipromosikan dari `payload.hand_id`.",
                "maxLength": 128
              },
              "match_id": {
                "type": "string",
                "nullable": true,
                "description": "Dipromosikan dari `payload.match_id`.",
                "maxLength": 128
              },
              "market_id": {
                "type": "string",
                "nullable": true,
                "description": "Dipromosikan dari `payload.market_id`.",
                "maxLength": 128
              },
              "side": {
                "type": "string",
                "nullable": true,
                "description": "Dipromosikan dari `payload.side`.",
                "maxLength": 64
              },
              "role": {
                "type": "string",
                "nullable": true,
                "description": "Dipromosikan dari `payload.role`.",
                "maxLength": 64
              },
              "net_result_amount": {
                "type": "string",
                "nullable": true,
                "description": "Dipromosikan dari `payload.net_result_amount`, sebagai string desimal dengan 18 tempat desimal.",
                "example": "-120.000000000000000000"
              },
              "payment_fingerprint": {
                "type": "string",
                "nullable": true,
                "description": "Dipromosikan dari `payload.payment_fingerprint`.",
                "maxLength": 255
              },
              "instrument_reference_hash": {
                "type": "string",
                "nullable": true,
                "description": "Dipromosikan dari `payload.instrument_reference_hash`.",
                "maxLength": 255
              },
              "withdrawal_address_hash": {
                "type": "string",
                "nullable": true,
                "description": "Dipromosikan dari `payload.withdrawal_address_hash` (atau `payload.destination_reference_hash`).",
                "maxLength": 255
              },
              "dispute_id": {
                "type": "string",
                "nullable": true,
                "description": "Dipromosikan dari `payload.dispute_id`.",
                "maxLength": 255
              },
              "chargeback_id": {
                "type": "string",
                "nullable": true,
                "description": "Dipromosikan dari `payload.chargeback_id`.",
                "maxLength": 255
              },
              "changed_field": {
                "type": "string",
                "nullable": true,
                "description": "Dipromosikan dari `payload.changed_field` (peristiwa perubahan keamanan).",
                "maxLength": 128
              },
              "identity_match_ref": {
                "type": "string",
                "nullable": true,
                "description": "Dipromosikan dari `payload.identity_match_ref` (kecocokan dengan registri perjudian yang bertanggung jawab).",
                "maxLength": 255
              },
              "schema_version": {
                "type": "integer",
                "description": "Versi skema envelope event. Saat ini `1`.",
                "example": 1
              },
              "expires_at": {
                "type": "string",
                "format": "date-time",
                "nullable": true,
                "description": "Waktu ketika peristiwa kedaluwarsa berdasarkan kelas retensinya dan dihapus: `occurred_at` ditambah periode kelas (secara default 14, 30, atau 90 hari, dapat disesuaikan per aplikasi). Null untuk peristiwa `monetary_or_compliance`, yang mengikuti retensi transaksi."
              },
              "rules_evaluated_count": {
                "type": "integer",
                "minimum": 0,
                "description": "Jumlah aturan event yang dievaluasi untuk event ini."
              },
              "rule_runs": {
                "type": "array",
                "description": "Setiap aturan yang cocok dengan event, yang terbaru terlebih dahulu.",
                "items": {
                  "$ref": "#/components/schemas/MonitoringEventRuleRun"
                }
              },
              "ip_enrichment": {
                "type": "object",
                "nullable": true,
                "description": "Pengayaan alamat IP event, atau null jika alamat tidak diperkaya. Lihat [Pengayaan IP](https://docs.didit.me/id/transaction-monitoring/ip-enrichment).",
                "properties": {
                  "ip_country_code": {
                    "type": "string",
                    "nullable": true,
                    "description": "Kode negara dari alamat tersebut."
                  },
                  "ip_city": {
                    "type": "string",
                    "nullable": true,
                    "description": "Kota dari alamat."
                  },
                  "asn_number": {
                    "type": "integer",
                    "nullable": true,
                    "description": "Nomor sistem otonom."
                  },
                  "asn_organization": {
                    "type": "string",
                    "nullable": true,
                    "description": "Organisasi yang mengoperasikan sistem otonom."
                  },
                  "is_vpn_or_tor": {
                    "type": "boolean",
                    "description": "Apakah alamat merupakan exit node VPN atau Tor yang diketahui."
                  },
                  "is_data_center": {
                    "type": "boolean",
                    "description": "Apakah alamat milik jaringan hosting atau pusat data."
                  },
                  "proxy_type": {
                    "type": "string",
                    "nullable": true,
                    "description": "Klasifikasi proksi dari alamat sebagai string opak, atau null."
                  },
                  "last_enriched_at": {
                    "type": "string",
                    "format": "date-time",
                    "nullable": true,
                    "description": "Waktu ketika alamat terakhir diperkaya."
                  }
                },
                "required": [
                  "ip_country_code",
                  "ip_city",
                  "asn_number",
                  "asn_organization",
                  "is_vpn_or_tor",
                  "is_data_center",
                  "proxy_type",
                  "last_enriched_at"
                ]
              },
              "subject_profile": {
                "type": "object",
                "nullable": true,
                "description": "Sinyal risiko email dan telepon yang di-cache dari subjek, atau null jika tidak ada profil untuk subjek tersebut.",
                "properties": {
                  "email_risk_score": {
                    "type": "integer",
                    "nullable": true,
                    "description": "Skor risiko email."
                  },
                  "email_deliverability": {
                    "type": "string",
                    "nullable": true,
                    "description": "Hasil evaluasi keterkiriman email."
                  },
                  "email_is_disposable": {
                    "type": "boolean",
                    "nullable": true,
                    "description": "Apakah alamat email bersifat sekali pakai."
                  },
                  "email_is_breached": {
                    "type": "boolean",
                    "nullable": true,
                    "description": "Apakah alamat email muncul dalam kebocoran data yang diketahui."
                  },
                  "email_social_count": {
                    "type": "integer",
                    "nullable": true,
                    "description": "Jumlah akun online yang terhubung ke alamat email."
                  },
                  "email_social_providers": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Nama layanan online tempat akun yang ditautkan ke alamat email ditemukan."
                  },
                  "phone_risk_score": {
                    "type": "integer",
                    "nullable": true,
                    "description": "Skor risiko telepon."
                  },
                  "phone_line_type": {
                    "type": "string",
                    "nullable": true,
                    "description": "Jenis saluran telepon."
                  },
                  "phone_carrier": {
                    "type": "string",
                    "nullable": true,
                    "description": "Nama operator telepon."
                  },
                  "phone_social_count": {
                    "type": "integer",
                    "nullable": true,
                    "description": "Jumlah akun online yang terhubung ke nomor telepon."
                  },
                  "phone_social_providers": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Nama layanan online tempat akun yang ditautkan ke nomor telepon ditemukan."
                  },
                  "source_provider": {
                    "type": "string",
                    "nullable": true,
                    "description": "Pengidentifikasi tidak transparan dari sumber profil."
                  },
                  "last_enriched_at": {
                    "type": "string",
                    "format": "date-time",
                    "nullable": true,
                    "description": "Waktu profil terakhir disegarkan."
                  }
                },
                "required": [
                  "email_risk_score",
                  "email_deliverability",
                  "email_is_disposable",
                  "email_is_breached",
                  "email_social_count",
                  "email_social_providers",
                  "phone_risk_score",
                  "phone_line_type",
                  "phone_carrier",
                  "phone_social_count",
                  "phone_social_providers",
                  "source_provider",
                  "last_enriched_at"
                ]
              },
              "tags": {
                "type": "array",
                "items": {
                  "type": "string"
                },
                "description": "Nama tag yang dilampirkan ke peristiwa (tindakan aturan `add_tags`)."
              }
            }
          }
        ]
      },
      "MonitoringEventRuleRun": {
        "type": "object",
        "properties": {
          "rule_uuid": {
            "type": "string",
            "format": "uuid",
            "description": "UUID aturan pemantauan transaksi."
          },
          "rule_title": {
            "type": "string",
            "description": "Judul aturan."
          },
          "library_key": {
            "type": "string",
            "nullable": true,
            "description": "Kunci pustaka saat aturan dipasang dari pustaka aturan, jika tidak maka null."
          },
          "matched": {
            "type": "boolean",
            "description": "Selalu `true`: hanya proses yang cocok yang dicatat."
          },
          "mode": {
            "type": "string",
            "enum": [
              "ACTIVE",
              "TEST"
            ],
            "description": "Mode aturan saat dijalankan. Eksekusi `TEST` mencatat bukti tetapi tidak menerapkan tindakan apa pun."
          },
          "is_async": {
            "type": "boolean",
            "description": "`true` saat eksekusi berasal dari proses korelasi asinkron, bukan dari permintaan ingest."
          },
          "severity": {
            "type": "string",
            "nullable": true,
            "enum": [
              "UNKNOWN",
              "LOW",
              "MEDIUM",
              "HIGH",
              "CRITICAL",
              null
            ],
            "description": "Tingkat keparahan aturan. Null untuk eksekusi `TEST` dan untuk aturan tanpa tingkat keparahan."
          },
          "score_delta": {
            "type": "integer",
            "description": "Seberapa besar proses ini mengubah skor event (0 untuk proses `TEST`)."
          },
          "action_summary": {
            "type": "string",
            "nullable": true,
            "description": "Ringkasan singkat tindakan yang diterapkan, misalnya `score +40; add_tag:VPN_LOGIN`. Null jika tidak ada yang diterapkan."
          },
          "matched_payload": {
            "type": "array",
            "description": "Kondisi dan agregasi yang cocok. Entri kondisi memuat `field`, `operator`, `expected_value`, `current_value`, `matched`, `group_index`, `group_logic`, dan `field_source` (`server`, `sdk`, atau `customer`); entri agregasi memuat `metric`, `field`, `operator`, `expected_value`, `computed_value`, `window`, `filters`, `matched`, dan `sample_references`.",
            "items": {
              "type": "object",
              "additionalProperties": true
            }
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "Waktu eksekusi aturan dicatat."
          }
        },
        "required": [
          "rule_uuid",
          "rule_title",
          "library_key",
          "matched",
          "mode",
          "is_async",
          "severity",
          "score_delta",
          "action_summary",
          "matched_payload",
          "created_at"
        ]
      },
      "MonitoringEventPage": {
        "type": "object",
        "description": "Satu halaman event pemantauan, `occurred_at` terbaru lebih dahulu.",
        "required": [
          "count",
          "next",
          "previous",
          "results"
        ],
        "properties": {
          "count": {
            "type": "integer",
            "description": "Jumlah event yang cocok, tepat hingga 100 dan dibatasi pada 100 di atasnya. Jangan menghitung jumlah halaman dari nilai ini; ikuti `next` hingga bernilai null."
          },
          "next": {
            "type": "string",
            "format": "uri",
            "nullable": true,
            "description": "URL halaman berikutnya, atau null pada halaman terakhir."
          },
          "previous": {
            "type": "string",
            "format": "uri",
            "nullable": true,
            "description": "URL halaman sebelumnya, atau null pada halaman pertama."
          },
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/MonitoringEvent"
            }
          }
        }
      },
      "MonitoringEventCreateRequest": {
        "type": "object",
        "description": "Envelope untuk event, sama untuk setiap kategori. Alias camelCase diterima: `eventId`, `eventCategory` (atau `category`), `actionType`, `occurredAt`, `timeZone` (atau `zoneId`), `deviceContext` (atau `device`), `transactionContext`, `customValues` (atau `props`); di dalam `subject`: `vendorData`, `entityType`, `fullName`; di dalam `session`: `sessionId`, `pageUrl`; di dalam `transaction_context`: `paymentReferenceId`.",
        "required": [
          "event_id",
          "event_category",
          "action_type",
          "occurred_at",
          "subject"
        ],
        "properties": {
          "event_id": {
            "type": "string",
            "maxLength": 128,
            "description": "Pengidentifikasi Anda untuk event tersebut, unik per aplikasi. Nilai ini merupakan kunci idempotensi: mengirim ulang `event_category`, `action_type`, `occurred_at`, `subject.vendor_data`, dan `payload` yang sama di bawahnya dianggap sebagai replay, sedangkan perbedaan apa pun akan menimbulkan konflik.",
            "example": "login-2026-10-17-000001"
          },
          "event_category": {
            "type": "string",
            "enum": [
              "auth",
              "session",
              "gameplay",
              "bonus",
              "affiliate",
              "payment",
              "dispute",
              "security",
              "responsible_gambling",
              "custom"
            ],
            "description": "Kategori peristiwa.",
            "example": "auth"
          },
          "action_type": {
            "type": "string",
            "minLength": 1,
            "maxLength": 128,
            "description": "Hal yang terjadi dalam kategori. Kosakata terbuka; tindakan terkelola yang tercantum di [Penyerapan peristiwa](https://docs.didit.me/id/transaction-monitoring/events) (misalnya `login`, `deposit_completed`, `chargeback_opened`) membuka validasi bertipe dan kolom aturan terkelola. Spasi di awal dan akhir akan dipangkas.",
            "example": "login"
          },
          "occurred_at": {
            "type": "string",
            "format": "date-time",
            "description": "Waktu ketika peristiwa terjadi di pihak Anda, ISO 8601 (nilai tanpa offset dibaca sebagai UTC). Tidak boleh lebih dari 7 hari di masa lalu dan tidak lebih dari 5 menit di masa depan.",
            "example": "2026-10-17T09:15:02.481Z"
          },
          "time_zone": {
            "type": "string",
            "nullable": true,
            "maxLength": 64,
            "description": "Zona waktu kejadian di pihak Anda, misalnya `Europe/Madrid`. Disimpan bersama peristiwa; tidak dikembalikan oleh endpoint baca."
          },
          "subject": {
            "type": "object",
            "description": "Pengguna atau perusahaan yang terkait dengan event tersebut. Nilai ini merujuk ke pengguna (atau perusahaan) dengan `vendor_data` ini di aplikasi Anda; entitas baru akan dibuat jika belum ada.",
            "required": [
              "vendor_data"
            ],
            "properties": {
              "vendor_data": {
                "type": "string",
                "minLength": 1,
                "maxLength": 255,
                "description": "ID Anda untuk subjek tersebut.",
                "example": "user-42"
              },
              "entity_type": {
                "type": "string",
                "maxLength": 32,
                "default": "individual",
                "description": "`company` menetapkan subjek sebagai perusahaan; nilai lainnya (default `individual`) menetapkannya sebagai perorangan. `vendor_data` yang sama dapat menamai satu dari masing-masing jenis.",
                "example": "individual"
              },
              "full_name": {
                "type": "string",
                "nullable": true,
                "maxLength": 512,
                "description": "Nama tampilan, hanya digunakan saat event ini membuat pengguna atau perusahaan."
              },
              "email": {
                "type": "string",
                "format": "email",
                "nullable": true,
                "description": "Divalidasi sebagai alamat email; tidak disimpan pada event."
              },
              "phone": {
                "type": "string",
                "nullable": true,
                "maxLength": 32,
                "description": "Divalidasi; tidak disimpan pada event."
              },
              "country": {
                "type": "string",
                "nullable": true,
                "maxLength": 3,
                "description": "Divalidasi; tidak disimpan pada event."
              }
            }
          },
          "business": {
            "type": "object",
            "description": "Bisnis yang memiliki event tersebut, jika berbeda dari subjek. Hanya `vendor_data` yang dibaca.",
            "additionalProperties": true,
            "properties": {
              "vendor_data": {
                "type": "string",
                "maxLength": 255,
                "description": "ID Anda untuk bisnis tersebut. Dapat difilter sebagai `business_vendor_data`.",
                "example": "merchant-7"
              }
            }
          },
          "session": {
            "type": "object",
            "description": "Konteks sesi Anda untuk peristiwa tersebut.",
            "properties": {
              "session_id": {
                "type": "string",
                "nullable": true,
                "maxLength": 255,
                "description": "Pengenal sesi Anda. Dapat difilter dan dikembalikan sebagai `session_id`."
              },
              "sequence": {
                "type": "integer",
                "nullable": true,
                "description": "Posisi event di dalam sesi. Dikembalikan sebagai `session_sequence`."
              },
              "page_url": {
                "type": "string",
                "nullable": true,
                "maxLength": 2048,
                "description": "Divalidasi; tidak disimpan pada event."
              },
              "referrer": {
                "type": "string",
                "nullable": true,
                "maxLength": 2048,
                "description": "Divalidasi; tidak disimpan pada event."
              }
            }
          },
          "device_context": {
            "type": "object",
            "additionalProperties": true,
            "description": "Konteks perangkat dan jaringan, disimpan sebagaimana dikirim dan dikembalikan oleh `GET /v3/events/{event_uuid}/`. Pada jalur server ini Didit tidak melihat koneksi pengguna akhir, sehingga IP yang diperkaya dan digunakan oleh aturan adalah `network_context.ip_address` sebagaimana Anda mengirimkannya.",
            "properties": {
              "fingerprint": {
                "type": "string",
                "maxLength": 255,
                "description": "Sidik jari perangkat. Dapat difilter sebagai `device_fingerprint`."
              },
              "persistent_device_id": {
                "type": "string",
                "maxLength": 255,
                "description": "Pengenal perangkat persisten Anda."
              },
              "bot_score": {
                "type": "integer",
                "description": "Skor bot dari deteksi Anda sendiri, sebagai bilangan bulat."
              },
              "network_context": {
                "type": "object",
                "additionalProperties": true,
                "properties": {
                  "ip_address": {
                    "type": "string",
                    "maxLength": 64,
                    "description": "Alamat IP pengguna akhir. Alamat publik diperkaya satu kali per alamat unik.",
                    "example": "203.0.113.42"
                  }
                }
              }
            }
          },
          "transaction_context": {
            "type": "object",
            "description": "Konteks uang. Nilai yang tidak kosong di sini juga memenuhi kunci payload yang diperlukan untuk tindakan.",
            "properties": {
              "amount": {
                "type": "string",
                "nullable": true,
                "description": "Jumlah sebagai string desimal (angka juga diterima).",
                "example": "1000.00"
              },
              "currency": {
                "type": "string",
                "nullable": true,
                "maxLength": 10,
                "description": "Kode mata uang."
              },
              "direction": {
                "type": "string",
                "nullable": true,
                "maxLength": 16,
                "description": "Arah pergerakan uang, misalnya `inbound` atau `outbound`."
              },
              "payment_reference_id": {
                "type": "string",
                "nullable": true,
                "maxLength": 255,
                "description": "Referensi pembayaran Anda. Dapat difilter sebagai `payment_reference_id`."
              }
            }
          },
          "payload": {
            "type": "object",
            "additionalProperties": true,
            "description": "Kolom domain kategori, maksimal 16384 byte setelah di-encode ke JSON. Beberapa tindakan memerlukan kunci (dalam `payload` atau `transaction_context`): `gameplay.p2p_settlement` membutuhkan `game_id`, `counterparty_vendor_data`, `stake_amount`, `net_result_amount`, `role`, dan salah satu dari `hand_id`, `round_id`, `match_id`; `gameplay.bet_placed` dan `gameplay.bet_settled` membutuhkan `game_id`; `payment.deposit_initiated`, `payment.deposit_completed`, `payment.withdrawal_requested`, dan `payment.withdrawal_completed` membutuhkan `payment_reference_id`, `amount`, `currency`, `payment_method`, `status`; `payment.withdrawal_address_changed` membutuhkan `withdrawal_address_hash`; `dispute.chargeback_opened`, `dispute.chargeback_won`, dan `dispute.chargeback_lost` membutuhkan `payment_reference_id` dan salah satu dari `dispute_id`, `chargeback_id`; `session.bot_signal_observed` membutuhkan `telemetry_schema_version` dan salah satu dari `bot_score`, `actions_per_minute`, `timing_variance_ms`, `pointer_entropy`, `keystroke_entropy`, `reaction_time_ms_p50`; `responsible_gambling.self_exclusion_match` membutuhkan `registry_source`, `exclusion_status`, `identity_match_ref`. Setiap tindakan `security` yang berakhiran `_changed` membutuhkan `changed_field`, ditambah `previous_reference_hash` atau `new_reference_hash` ketika kolom tersebut berupa `password`, `mfa_method`, `mfa`, `email`, `phone`, `withdrawal_address`, `payout_method`, atau `api_key`. Kirimkan hash dan referensi, jangan pernah nomor kartu, alamat penarikan lengkap, hash kata sandi, atau rahasia MFA."
          },
          "custom_values": {
            "type": "object",
            "description": "Hingga 100 kunci milik Anda sendiri, dapat diakses dari aturan sebagai `custom_values.<key>`. Nilai harus berupa skalar (string, number, boolean, atau null); objek bersarang dan larik akan ditolak.",
            "additionalProperties": {
              "nullable": true,
              "oneOf": [
                {
                  "type": "string"
                },
                {
                  "type": "number"
                },
                {
                  "type": "boolean"
                }
              ]
            }
          }
        },
        "example": {
          "event_id": "login-2026-10-17-000001",
          "event_category": "auth",
          "action_type": "login",
          "occurred_at": "2026-10-17T09:15:02.481Z",
          "time_zone": "Europe/Madrid",
          "subject": {
            "vendor_data": "user-42",
            "entity_type": "individual"
          },
          "session": {
            "session_id": "web-session-abc",
            "sequence": 142
          },
          "device_context": {
            "fingerprint": "fp-a8c1",
            "network_context": {
              "ip_address": "203.0.113.42"
            }
          },
          "payload": {
            "method": "password"
          },
          "custom_values": {
            "vip_tier": "gold"
          }
        }
      },
      "MonitoringEventIngestResult": {
        "type": "object",
        "description": "Hasil pemrosesan satu event. Struktur yang sama dikembalikan untuk event baru dan untuk pemutaran ulang yang idempoten.",
        "required": [
          "event_uuid",
          "event_id",
          "status",
          "score",
          "rules_evaluated_count",
          "rules_matched_count",
          "correlation_pending",
          "retention_class",
          "expires_at",
          "idempotent_replay",
          "rule_matches"
        ],
        "properties": {
          "event_uuid": {
            "type": "string",
            "format": "uuid",
            "description": "Pengidentifikasi Didit untuk event yang disimpan."
          },
          "event_id": {
            "type": "string",
            "description": "`event_id` Anda."
          },
          "status": {
            "type": "string",
            "enum": [
              "ACCEPTED",
              "APPROVED",
              "IN_REVIEW",
              "DECLINED"
            ],
            "description": "Status setelah aturan real-time dijalankan. Lihat `MonitoringEvent.status`."
          },
          "score": {
            "type": "integer",
            "description": "Skor setelah aturan real-time dijalankan."
          },
          "rules_evaluated_count": {
            "type": "integer",
            "minimum": 0,
            "description": "Jumlah aturan event yang dievaluasi dalam permintaan. 0 dalam aplikasi sandbox, tempat tidak ada aturan yang berjalan."
          },
          "rules_matched_count": {
            "type": "integer",
            "minimum": 0,
            "description": "Jumlah aturan yang cocok, termasuk aturan mode `TEST`."
          },
          "correlation_pending": {
            "type": "boolean",
            "description": "`true` jika aturan asinkron masih harus dijalankan. Baca `GET /v3/events/{event_uuid}/` beberapa menit kemudian untuk `status` dan `score` akhir."
          },
          "retention_class": {
            "type": "string",
            "enum": [
              "low_value",
              "standard",
              "risk_relevant",
              "monetary_or_compliance"
            ],
            "description": "Kelas retensi, setelah promosi apa pun oleh aturan yang cocok."
          },
          "expires_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Waktu ketika peristiwa kedaluwarsa berdasarkan kelas retensinya dan dihapus. Null untuk peristiwa `monetary_or_compliance` (pembayaran dan sengketa)."
          },
          "idempotent_replay": {
            "type": "boolean",
            "description": "`true` jika event dengan `event_id` ini dan konten yang sama telah disimpan sebelumnya; nilainya adalah nilai dari event yang disimpan dan tidak ada aturan yang dijalankan ulang."
          },
          "rule_matches": {
            "type": "array",
            "description": "Aturan yang cocok dengan event.",
            "items": {
              "type": "object",
              "required": [
                "rule_id",
                "library_key",
                "mode",
                "is_async"
              ],
              "properties": {
                "rule_id": {
                  "type": "string",
                  "format": "uuid",
                  "description": "UUID aturan."
                },
                "library_key": {
                  "type": "string",
                  "nullable": true,
                  "description": "Kunci pustaka saat aturan dipasang dari pustaka aturan, jika tidak maka null."
                },
                "mode": {
                  "type": "string",
                  "enum": [
                    "ACTIVE",
                    "TEST"
                  ],
                  "description": "Aturan `TEST` mencatat kecocokan tetapi tidak menerapkan tindakan apa pun."
                },
                "is_async": {
                  "type": "boolean",
                  "description": "`true` saat kecocokan berasal dari proses asinkron."
                }
              }
            }
          }
        }
      },
      "ComplianceList": {
        "type": "object",
        "description": "Daftar blokir, daftar izin, atau daftar kustom dari satu aplikasi.",
        "required": [
          "uuid",
          "name",
          "description",
          "list_type",
          "entry_type",
          "is_system",
          "entry_count",
          "last_entry_added_at",
          "created_at",
          "updated_at"
        ],
        "properties": {
          "uuid": {
            "type": "string",
            "format": "uuid",
            "description": "Pengidentifikasi daftar. Gunakan ini sebagai `list_uuid` di endpoint daftar dan entri, serta sebagai nilai dari kondisi aturan alur kerja atau transaksi dengan `value_type: \"list\"`."
          },
          "name": {
            "type": "string",
            "maxLength": 255,
            "description": "Nama daftar, unik di antara daftar milik aplikasi."
          },
          "description": {
            "type": "string",
            "description": "Deskripsi teks bebas. String kosong jika tidak diatur."
          },
          "list_type": {
            "type": "string",
            "enum": [
              "blocklist",
              "allowlist",
              "custom"
            ],
            "description": "`blocklist`: kecocokan akan menolak sesi atau transaksi (hanya daftar sistem, satu per tipe entri). `allowlist`: item yang cocok dipercaya, misalnya allowlist wajah melewati tindakan untuk wajah duplikat; tidak pernah menimpa kecocokan daftar blokir. `custom`: digunakan dalam kondisi aturan alur kerja dan transaksi (`value_type: \"list\"`)."
          },
          "entry_type": {
            "type": "string",
            "enum": [
              "face",
              "document",
              "phone",
              "email",
              "ip_address",
              "device_fingerprint",
              "wallet_address",
              "bank_account",
              "country",
              "user",
              "business",
              "key"
            ],
            "description": "Apa yang dimuat dalam daftar: `face`, `document` (nomor dokumen), `phone`, `email`, `ip_address` (alamat atau rentang CIDR), `device_fingerprint`, `wallet_address`, `bank_account`, `country` (ISO 3166-1 alpha-3), `user` atau `business` (`vendor_data` Anda), atau `key` (string apa pun). Ini menentukan cara nilai entri divalidasi dan dicocokkan."
          },
          "is_system": {
            "type": "boolean",
            "description": "`true` untuk daftar yang disediakan oleh Didit: satu daftar blokir per tipe entri (`face`, `document`, `phone`, `email`, `ip_address`, `device_fingerprint`, `wallet_address`, `bank_account`, `user`, `business`), daftar kustom **Negara Berisiko Tinggi**, dan daftar izin sistem. Daftar sistem tidak dapat diganti namanya, diedit, atau dihapus; Anda dapat menambahkan dan menghapus entrinya."
          },
          "entry_count": {
            "type": "integer",
            "minimum": 0,
            "description": "Jumlah entri yang saat ini ada dalam daftar."
          },
          "last_entry_added_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Waktu entri saat ini yang terbaru ditambahkan. `null` untuk daftar kosong."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "Waktu daftar dibuat."
          },
          "updated_at": {
            "type": "string",
            "format": "date-time",
            "description": "Waktu daftar terakhir diperbarui."
          }
        }
      },
      "ComplianceListEntry": {
        "type": "object",
        "description": "Satu nilai dalam sebuah daftar.",
        "required": [
          "uuid",
          "value",
          "display_label",
          "comment",
          "added_by",
          "reference_session_id",
          "reference_session_number",
          "reference_session_type",
          "reference_object_uuid",
          "metadata",
          "created_at"
        ],
        "properties": {
          "uuid": {
            "type": "string",
            "format": "uuid",
            "description": "Pengidentifikasi entri. Gunakan sebagai `entry_uuid` dalam operasi Hapus entri daftar."
          },
          "value": {
            "type": "string",
            "description": "Nilai yang terdaftar: nomor telepon dalam format E.164, alamat email, nomor dokumen, alamat IP atau rentang CIDR, sidik jari perangkat, alamat dompet, rekening bank, kode negara ISO 3166-1 alpha-3, `vendor_data`, string apa pun pada daftar `key`, atau UUID wajah yang disimpan pada daftar wajah. Nilai yang Anda kirim disimpan dalam huruf kecil, kecuali nomor telepon dan kode negara. Pencocokan tidak membedakan huruf besar dan kecil."
          },
          "display_label": {
            "type": "string",
            "nullable": true,
            "maxLength": 512,
            "description": "Label yang mudah dibaca manusia. Didit mengisinya untuk entri yang diambil dari sesi (misalnya nama pemegang dan nomor dokumen) saat Anda tidak mengirimkannya."
          },
          "comment": {
            "type": "string",
            "description": "Catatan teks bebas. String kosong jika tidak diatur."
          },
          "added_by": {
            "type": "string",
            "nullable": true,
            "description": "Pihak yang menambahkan entri: `api` (kunci API), alamat email pengguna konsol atau `console`, `system` atau `migration` (entri yang dibuat Didit), atau `rule` (tindakan aturan transaksi atau aturan pemantauan)."
          },
          "reference_session_id": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "Sesi verifikasi tempat entri tersebut diambil. `null` jika entri ditambahkan berdasarkan nilai."
          },
          "reference_session_number": {
            "type": "integer",
            "nullable": true,
            "description": "Nomor sesi tersebut dalam cakupan aplikasi, seperti yang ditampilkan di konsol."
          },
          "reference_session_type": {
            "type": "string",
            "nullable": true,
            "enum": [
              "kyc",
              "kyb",
              null
            ],
            "description": "`kyc` untuk sesi verifikasi perorangan, `kyb` untuk sesi verifikasi bisnis, `null` ketika tidak ada sesi."
          },
          "reference_object_uuid": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "Rekaman yang diwakili oleh entri: rekaman wajah, dokumen, telepon, atau email yang dibaca dari sesi, wajah yang dibuat melalui Unggah wajah ke daftar, atau UUID yang Anda kirim (misalnya UUID transaksi atau `didit_internal_id` milik pengguna)."
          },
          "metadata": {
            "type": "object",
            "nullable": true,
            "additionalProperties": true,
            "description": "Konteks tambahan. Berisi kunci yang ditetapkan Didit (tercantum di sini) yang digabungkan dengan `metadata` apa pun yang Anda kirimkan saat membuat entri, dikembalikan seperti yang disimpan. `null` jika tidak ada.",
            "properties": {
              "reference_image_url": {
                "type": "string",
                "description": "Entri wajah: URL bertanda tangan berumur pendek, diterbitkan kembali pada setiap panggilan; `null` untuk kunci API dengan cakupan terbatas tanpa `media: read`. Tidak ada jika tidak ada gambar milik entri tersebut."
              },
              "front_image_url": {
                "type": "string",
                "description": "Entri dokumen yang memuat gambar depan dokumen: URL bertanda tangan berumur pendek, diterbitkan ulang pada setiap panggilan; `null` untuk kunci API dengan cakupan tanpa `media: read`."
              },
              "full_name": {
                "type": "string",
                "description": "Entri dokumen yang diambil dari sesi: nama lengkap pemegang."
              },
              "issuing_state": {
                "type": "string",
                "description": "Entri dokumen yang diambil dari sesi: negara penerbit ISO 3166-1 alpha-3."
              },
              "document_type": {
                "type": "string",
                "description": "Entri dokumen yang diambil dari sesi: kode jenis dokumen, misalnya `P`, `ID` atau `DL`."
              },
              "region": {
                "type": "string",
                "description": "Entri dokumen yang diambil dari sesi: negara bagian atau provinsi penerbit dokumen yang diterbitkan secara regional, kosong jika tidak berlaku. Tidak diatur oleh penambahan item sesi ke daftar blokir."
              },
              "document_number": {
                "type": "string",
                "description": "Entri dokumen yang diambil dari sesi: nomor dokumen."
              },
              "face_image_source": {
                "type": "string",
                "enum": [
                  "front_image_camera_front",
                  "back_image_camera_front"
                ],
                "description": "Entri wajah yang diambil dari swafoto pengambilan dokumen: swafoto yang mana. Tidak ada untuk wajah dari liveness."
              },
              "reference_node_id": {
                "type": "string",
                "nullable": true,
                "description": "Entri wajah yang diambil dari swafoto dari pengambilan dokumen: node verifikasi identitas asal swafoto tersebut."
              },
              "fingerprint_tier": {
                "type": "string",
                "nullable": true,
                "enum": [
                  "persistent_id",
                  "composite_hash",
                  "legacy_fp",
                  "unknown",
                  null
                ],
                "description": "Entri sidik jari perangkat yang diambil dari sesi: bagaimana sidik jari tersebut diturunkan. `persistent_id` mengidentifikasi satu perangkat; `composite_hash` dan `legacy_fp` dapat digunakan bersama oleh perangkat dari model yang sama."
              },
              "sandbox": {
                "type": "boolean",
                "description": "`true` pada entri wajah yang diunggah dalam aplikasi sandbox; entri tersebut tidak mencocokkan apa pun."
              },
              "reference_type": {
                "type": "string",
                "enum": [
                  "transaction",
                  "vendor_user",
                  "vendor_business"
                ],
                "description": "Ditetapkan oleh Anda: apa yang ditunjuk oleh `reference_object_uuid`, sehingga konsol menautkan kembali ke sana."
              },
              "reference_id": {
                "type": "string",
                "description": "Ditetapkan oleh Anda: pengidentifikasi rekaman sumber."
              }
            }
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "Waktu ketika entri ditambahkan."
          }
        }
      },
      "BlocklistedItem": {
        "type": "object",
        "description": "Satu wajah, dokumen identitas, nomor telepon, atau alamat email yang masuk daftar blokir dari suatu sesi verifikasi. Kolom yang tidak berlaku untuk `type` item tersebut bernilai `null`.",
        "required": [
          "type",
          "session_id",
          "session_number",
          "blocklisted_at",
          "face_image",
          "document_type",
          "document_number",
          "front_image",
          "phone_number",
          "country_code",
          "email"
        ],
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "face",
              "document",
              "phone",
              "email"
            ],
            "description": "Apa yang dimasukkan ke daftar blokir."
          },
          "session_id": {
            "type": "string",
            "format": "uuid",
            "description": "Sesi verifikasi tempat item tersebut berada."
          },
          "session_number": {
            "type": "integer",
            "nullable": true,
            "description": "Nomor sesi tersebut dalam cakupan aplikasi, seperti yang ditampilkan di konsol."
          },
          "blocklisted_at": {
            "type": "string",
            "format": "date-time",
            "description": "Waktu item terakhir kali dimasukkan ke daftar blokir."
          },
          "face_image": {
            "type": "string",
            "nullable": true,
            "description": "Item wajah: URL bertanda tangan berumur pendek, diterbitkan kembali pada setiap panggilan; `null` untuk kunci API dengan cakupan terbatas tanpa `media: read`. Juga `null` jika tidak ada gambar referensi yang disimpan."
          },
          "document_type": {
            "type": "string",
            "nullable": true,
            "description": "Item dokumen: kode jenis dokumen, misalnya `P` (paspor), `ID` (KTP/ID nasional), `DL` (SIM) atau `RP` (izin tinggal)."
          },
          "document_number": {
            "type": "string",
            "nullable": true,
            "description": "Item dokumen: nomor dokumen, atau nomor pribadi jika dokumen tidak memilikinya."
          },
          "front_image": {
            "type": "string",
            "nullable": true,
            "description": "Item dokumen: gambar depan dokumen, URL bertanda tangan berumur pendek, diterbitkan ulang pada setiap panggilan; `null` untuk kunci API dengan cakupan tanpa `media: read`."
          },
          "phone_number": {
            "type": "string",
            "nullable": true,
            "description": "Item telepon: nomor telepon dalam E.164."
          },
          "country_code": {
            "type": "string",
            "nullable": true,
            "description": "Item telepon: negara ISO 3166-1 alpha-2 dari nomor tersebut."
          },
          "email": {
            "type": "string",
            "nullable": true,
            "description": "Item email: alamat email."
          }
        }
      },
      "TransactionNote": {
        "type": "object",
        "description": "Satu catatan pada linimasa peninjauan transaksi yang dipantau.",
        "required": [
          "uuid",
          "note",
          "actor_email",
          "actor_name",
          "metadata",
          "created_at"
        ],
        "properties": {
          "uuid": {
            "type": "string",
            "format": "uuid",
            "description": "Pengidentifikasi catatan."
          },
          "note": {
            "type": "string",
            "description": "Isi catatan teks biasa."
          },
          "actor_email": {
            "type": "string",
            "format": "email",
            "nullable": true,
            "description": "Email pengguna Console yang menulis catatan atau mengubah status. `null` untuk catatan yang dibuat dengan kunci API dan untuk catatan yang ditambahkan Didit secara otomatis."
          },
          "actor_name": {
            "type": "string",
            "nullable": true,
            "description": "Nama tampilan pengguna Console (email mereka jika mereka tidak memiliki nama). `Rule Engine` pada catatan yang ditambahkan Didit secara otomatis. `null` untuk catatan yang dibuat dengan kunci API."
          },
          "metadata": {
            "type": "object",
            "description": "Membedakan jenis catatan. Catatan yang ditulis melalui API atau Konsol memuat `mentioned_emails`. Perubahan status yang dilakukan di Konsol membawa `type: status_change` beserta `previous_status`, `new_status`, `reason_code`, dan `reason_label`. Catatan yang ditambahkan Didit membawa `source`: `rule_action` (dengan `rule_uuid`) untuk tindakan `add_note` aturan, atau `remediation_session` untuk masalah pembuatan sesi verifikasi tindakan pengguna.",
            "properties": {
              "mentioned_emails": {
                "type": "array",
                "items": {
                  "type": "string",
                  "format": "email"
                },
                "description": "Anggota organisasi yang disebutkan, ditulis dalam huruf kecil dan dideduplikasi. Kosong jika tidak ada yang disebutkan."
              },
              "type": {
                "type": "string",
                "enum": [
                  "status_change"
                ],
                "description": "Hadir pada catatan yang merekam perubahan status yang dibuat di Console."
              },
              "previous_status": {
                "type": "string",
                "enum": [
                  "APPROVED",
                  "IN_REVIEW",
                  "DECLINED",
                  "AWAITING_USER"
                ],
                "description": "Status sebelum perubahan."
              },
              "new_status": {
                "type": "string",
                "enum": [
                  "APPROVED",
                  "IN_REVIEW",
                  "DECLINED",
                  "AWAITING_USER"
                ],
                "description": "Status setelah perubahan."
              },
              "reason_code": {
                "type": "string",
                "nullable": true,
                "description": "Kode alasan yang diberikan bersama perubahan."
              },
              "reason_label": {
                "type": "string",
                "nullable": true,
                "description": "Label alasan yang diberikan bersama perubahan."
              },
              "source": {
                "type": "string",
                "enum": [
                  "rule_action",
                  "remediation_session"
                ],
                "description": "Hadir pada catatan yang ditambahkan Didit secara otomatis."
              },
              "rule_uuid": {
                "type": "string",
                "format": "uuid",
                "description": "Aturan yang tindakan `add_note`-nya menulis catatan tersebut (dengan `source: rule_action`)."
              }
            }
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "Waktu catatan disimpan."
          }
        }
      },
      "TransactionSummary": {
        "type": "object",
        "description": "Ringkasan transaksi yang dipantau, struktur yang dicantumkan oleh `GET /v3/transactions/`. Panggil `GET /v3/transactions/{transaction_id}/` dengan `uuid` untuk pihak, alert, dan eksekusi aturan.",
        "properties": {
          "uuid": {
            "type": "string",
            "format": "uuid",
            "description": "UUID transaksi Didit. Gunakan sebagai `{transaction_id}` pada endpoint transaksi."
          },
          "transaction_number": {
            "type": "integer",
            "nullable": true,
            "description": "Nomor berurutan dalam cakupan aplikasi yang ditampilkan di Konsol."
          },
          "txn_id": {
            "type": "string",
            "nullable": true,
            "description": "Pengenal Anda sendiri dari panggilan pembuatan. Unik per aplikasi."
          },
          "transaction_type": {
            "type": "string",
            "description": "Kategori sebagaimana disimpan: `finance`, `kyc`, `travelRule`, `userPlatformEvent`, `gamblingBet`, `gamblingLimitChange`, `gamblingBonusChange`, atau `auditTrailEvent`."
          },
          "action_type": {
            "type": "string",
            "description": "Subtipe dalam kategori tersebut, misalnya `withdrawal`."
          },
          "status": {
            "type": "string",
            "enum": [
              "APPROVED",
              "IN_REVIEW",
              "DECLINED",
              "AWAITING_USER"
            ],
            "description": "Keputusan pemantauan saat ini."
          },
          "source": {
            "type": "string",
            "enum": [
              "LIVE",
              "IMPORTED"
            ],
            "description": "`LIVE` untuk transaksi yang dikirimkan untuk pemantauan, `IMPORTED` untuk impor historis."
          },
          "direction": {
            "type": "string",
            "enum": [
              "INBOUND",
              "OUTBOUND"
            ],
            "description": "Arah relatif terhadap subjek."
          },
          "amount": {
            "type": "string",
            "description": "Jumlah sebagai string desimal dengan nol di belakangnya dihapus (hingga 18 tempat desimal)."
          },
          "currency": {
            "type": "string",
            "description": "Kode mata uang atau simbol aset kripto dari `amount`."
          },
          "currency_type": {
            "type": "string",
            "nullable": true,
            "description": "`fiat` atau `crypto` jika diketahui."
          },
          "preferred_currency_amount": {
            "type": "string",
            "nullable": true,
            "description": "`amount` dikonversi ke mata uang pilihan aplikasi, ketika kurs tersedia."
          },
          "preferred_currency_code": {
            "type": "string",
            "nullable": true,
            "description": "Mata uang dari `preferred_currency_amount`."
          },
          "payment_details": {
            "type": "string",
            "nullable": true,
            "description": "Referensi pembayaran teks bebas."
          },
          "txn_date": {
            "type": "string",
            "format": "date-time",
            "description": "Kapan transaksi terjadi."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "Waktu ketika Didit mencatatnya."
          },
          "score": {
            "type": "integer",
            "description": "Skor risiko. Lebih tinggi berarti lebih berisiko."
          },
          "severity": {
            "type": "string",
            "nullable": true,
            "enum": [
              "UNKNOWN",
              "LOW",
              "MEDIUM",
              "HIGH",
              "CRITICAL",
              null
            ],
            "description": "Tingkat keparahan risiko, `null` sampai ada yang menetapkannya."
          },
          "decision_reason_code": {
            "type": "string",
            "nullable": true,
            "description": "Alasan yang dapat dibaca mesin untuk `status` saat ini."
          },
          "decision_reason_label": {
            "type": "string",
            "nullable": true,
            "description": "Label yang mudah dibaca manusia untuk `decision_reason_code`."
          },
          "tags": {
            "type": "array",
            "description": "Tag pada transaksi.",
            "items": {
              "type": "object",
              "properties": {
                "uuid": {
                  "type": "string",
                  "format": "uuid"
                },
                "name": {
                  "type": "string"
                },
                "color": {
                  "type": "string",
                  "description": "Warna hex, misalnya `#F59E0B`."
                },
                "description": {
                  "type": "string",
                  "nullable": true
                },
                "source": {
                  "type": "string",
                  "enum": [
                    "didit",
                    "custom"
                  ],
                  "description": "Tag bawaan Didit atau tag kustom."
                }
              }
            }
          },
          "subject_name": {
            "type": "string",
            "nullable": true,
            "description": "Nama lengkap pihak `APPLICANT`."
          },
          "subject_vendor_data": {
            "type": "string",
            "nullable": true,
            "description": "`vendor_data` Anda untuk pemohon."
          },
          "subject_type": {
            "type": "string",
            "nullable": true,
            "enum": [
              "user",
              "business",
              null
            ],
            "description": "Apakah pemohon terhubung ke pengguna atau bisnis Didit; `null` jika tidak terhubung ke keduanya."
          },
          "subject_uuid": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "UUID pengguna atau bisnis Didit yang ditautkan ke pemohon."
          },
          "subject_country": {
            "type": "string",
            "nullable": true,
            "description": "Kode negara pemohon."
          },
          "counterparty_name": {
            "type": "string",
            "nullable": true,
            "description": "Nama lengkap pihak `COUNTERPARTY`, jika ada."
          },
          "counterparty_vendor_data": {
            "type": "string",
            "nullable": true,
            "description": "`vendor_data` Anda untuk pihak lawan."
          },
          "counterparty_country": {
            "type": "string",
            "nullable": true,
            "description": "Kode negara pihak lawan."
          },
          "assigned_to_name": {
            "type": "string",
            "nullable": true,
            "description": "Nama peninjau Console yang ditugaskan ke transaksi."
          },
          "travel_rule_status": {
            "type": "string",
            "nullable": true,
            "description": "Status transfer Travel Rule milik transaksi, atau `null` jika tidak ada."
          },
          "application_id": {
            "type": "string",
            "format": "uuid",
            "description": "Aplikasi yang memiliki transaksi tersebut."
          },
          "application_name": {
            "type": "string",
            "nullable": true,
            "description": "Nama aplikasi tersebut."
          },
          "organization_id": {
            "type": "string",
            "format": "uuid",
            "description": "Organisasi yang memiliki aplikasi."
          },
          "organization_name": {
            "type": "string",
            "nullable": true,
            "description": "Nama organisasi tersebut."
          }
        }
      },
      "ApplicationAnalyticsDataPoint": {
        "type": "object",
        "description": "Jumlah sesi untuk satu hari, berdasarkan tanggal pembuatan (UTC). Setiap jumlah mencerminkan status sesi saat ini. Titik-titik data dari periode sebelumnya membawa setidaknya kolom yang wajib diisi.",
        "required": [
          "rounded_date",
          "total",
          "approved",
          "declined",
          "canceled",
          "pending"
        ],
        "properties": {
          "rounded_date": {
            "type": "string",
            "format": "date",
            "description": "Hari, `YYYY-MM-DD`."
          },
          "total": {
            "type": "integer",
            "description": "Sesi yang dibuat pada hari tersebut."
          },
          "approved": {
            "type": "integer",
            "description": "Dari jumlah tersebut, sesi dengan status `Approved` atau `Kyc Expired`."
          },
          "declined": {
            "type": "integer",
            "description": "Sesi `Declined`."
          },
          "canceled": {
            "type": "integer",
            "description": "Sesi `Expired` atau `Abandoned`."
          },
          "pending": {
            "type": "integer",
            "description": "Sesi `Not Started`, `In Progress`, atau `In Review`."
          },
          "in_review": {
            "type": "integer",
            "description": "Sesi `In Review`."
          },
          "expired": {
            "type": "integer",
            "description": "Sesi `Expired`."
          },
          "abandoned": {
            "type": "integer",
            "description": "Sesi `Abandoned`."
          },
          "in_progress": {
            "type": "integer",
            "description": "Sesi `In Progress`."
          },
          "not_started": {
            "type": "integer",
            "description": "Sesi `Not Started`."
          },
          "manually_approved": {
            "type": "integer",
            "description": "Sesi yang disetujui oleh peninjau setelah alur kerja memberikan keputusan lain."
          },
          "manually_declined": {
            "type": "integer",
            "description": "Sesi yang ditolak oleh peninjau setelah alur kerja memberikan keputusan lain."
          }
        }
      },
      "ApplicationAnalyticsRequestBreakdown": {
        "type": "object",
        "description": "Total status untuk rentang tersebut. Rincian periode sebelumnya memuat setidaknya kolom yang wajib diisi.",
        "required": [
          "total_approved",
          "total_in_review",
          "total_declined",
          "total_canceled",
          "total_pending"
        ],
        "properties": {
          "total_approved": {
            "type": "integer",
            "description": "Sesi `Approved` atau `Kyc Expired`."
          },
          "total_in_review": {
            "type": "integer",
            "description": "Sesi `In Review`."
          },
          "total_declined": {
            "type": "integer",
            "description": "Sesi `Declined`."
          },
          "total_canceled": {
            "type": "integer",
            "description": "Sesi `Expired` atau `Abandoned`."
          },
          "total_pending": {
            "type": "integer",
            "description": "Sesi `Not Started`, `In Progress`, atau `In Review` (termasuk `total_in_review`)."
          },
          "total_expired": {
            "type": "integer",
            "description": "Sesi `Expired`."
          },
          "total_abandoned": {
            "type": "integer",
            "description": "Sesi `Abandoned`."
          },
          "total_in_progress": {
            "type": "integer",
            "description": "Sesi `In Progress`."
          },
          "total_not_started": {
            "type": "integer",
            "description": "Sesi `Not Started`."
          },
          "total_manually_approved": {
            "type": "integer",
            "description": "Disetujui oleh peninjau."
          },
          "total_manually_declined": {
            "type": "integer",
            "description": "Ditolak oleh peninjau."
          }
        }
      },
      "ApplicationAnalyticsCountryCount": {
        "type": "object",
        "properties": {
          "country": {
            "type": "string",
            "description": "Nama negara."
          },
          "country_code": {
            "type": "string",
            "description": "Kode negara dua huruf."
          },
          "session_count": {
            "type": "integer",
            "description": "Sesi dari negara tersebut."
          }
        }
      },
      "ApplicationAnalyticsLocationStats": {
        "type": "object",
        "properties": {
          "ip_countries": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ApplicationAnalyticsCountryCount"
            },
            "description": "Negara dari alamat IP pengguna, sesi terbanyak terlebih dahulu."
          },
          "countries": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ApplicationAnalyticsCountryCount"
            },
            "description": "Daftar yang sama dengan `ip_countries`."
          },
          "id_countries": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ApplicationAnalyticsCountryCount"
            },
            "description": "Negara penerbit dari dokumen identitas yang diverifikasi, sesi terbanyak terlebih dahulu."
          },
          "conversion_by_country": {
            "type": "array",
            "description": "Per negara penerbit dokumen: sesi yang selesai (disetujui, ditolak, atau dalam peninjauan) dan berapa banyak yang disetujui. Sesi yang paling banyak selesai ditampilkan terlebih dahulu.",
            "items": {
              "type": "object",
              "properties": {
                "country": {
                  "type": "string"
                },
                "country_code": {
                  "type": "string"
                },
                "finished": {
                  "type": "integer"
                },
                "approved": {
                  "type": "integer"
                }
              }
            }
          },
          "cities": {
            "type": "array",
            "description": "Hingga 100 kota IP, sesi terbanyak terlebih dahulu.",
            "items": {
              "type": "object",
              "properties": {
                "location": {
                  "type": "string",
                  "description": "`City, Country`."
                },
                "session_count": {
                  "type": "integer"
                },
                "latitude": {
                  "type": "number",
                  "nullable": true
                },
                "longitude": {
                  "type": "number",
                  "nullable": true
                }
              }
            }
          }
        }
      },
      "ApplicationAnalyticsDemographicStats": {
        "type": "object",
        "properties": {
          "age_distribution": {
            "type": "object",
            "description": "Sesi per kelompok usia dari dokumen identitas. Kosong jika tidak ada data.",
            "properties": {
              "under_18": {
                "type": "integer"
              },
              "18_24": {
                "type": "integer"
              },
              "25_34": {
                "type": "integer"
              },
              "35_44": {
                "type": "integer"
              },
              "45_64": {
                "type": "integer"
              },
              "65_plus": {
                "type": "integer"
              }
            },
            "additionalProperties": {
              "type": "integer"
            }
          },
          "gender_distribution": {
            "type": "object",
            "description": "Sesi per kode jenis kelamin dokumen: `M`, `F`, atau `U` (tidak diketahui).",
            "additionalProperties": {
              "type": "integer"
            }
          }
        }
      },
      "ApplicationAnalyticsDeviceDetails": {
        "type": "object",
        "description": "Lima teratas dari masing-masing, sesi terbanyak terlebih dahulu.",
        "properties": {
          "device_models": {
            "type": "array",
            "description": "Merek perangkat: `Apple`, `Android`, `LG`, selebihnya dikelompokkan sebagai `Other`.",
            "items": {
              "type": "object",
              "properties": {
                "device": {
                  "type": "string"
                },
                "count": {
                  "type": "integer"
                }
              }
            }
          },
          "browsers": {
            "type": "array",
            "description": "Browser: `Chrome`, `Safari`, `Didit App`, `Firefox`, selebihnya dikelompokkan sebagai `Other`.",
            "items": {
              "type": "object",
              "properties": {
                "browser": {
                  "type": "string"
                },
                "count": {
                  "type": "integer"
                }
              }
            }
          },
          "operating_systems": {
            "type": "array",
            "description": "Sistem operasi.",
            "items": {
              "type": "object",
              "properties": {
                "os": {
                  "type": "string"
                },
                "count": {
                  "type": "integer"
                }
              }
            }
          }
        }
      },
      "ApplicationAnalyticsWorkflowFunnel": {
        "type": "object",
        "description": "Menggunakan ID alur kerja sebagai kunci. `total` adalah sesi yang dimulai pada alur kerja tersebut; `steps` menghitung sesi yang mencapai setiap langkah (`OCR`, `LIVENESS`, `FACE_MATCH`, `AML`, `POA`, `PHONE`, `EMAIL`, `NFC`, `DATABASE_VALIDATION`, `QUESTIONNAIRE`, `IP_ANALYSIS`, `AGE_ESTIMATION`, `KYB_REGISTRY`, `KYB_DOCUMENTS`, `KYB_KEY_PEOPLE`). Mencapai suatu langkah bukan berarti lolos dari langkah tersebut.",
        "additionalProperties": {
          "type": "object",
          "properties": {
            "total": {
              "type": "integer"
            },
            "steps": {
              "type": "object",
              "additionalProperties": {
                "type": "object",
                "properties": {
                  "reached": {
                    "type": "integer"
                  }
                }
              }
            }
          }
        }
      },
      "ApplicationAnalyticsVerificationTimeStats": {
        "type": "object",
        "description": "Waktu aktif yang dihabiskan pengguna untuk memverifikasi, mengabaikan jeda tidak aktif. Berupa objek kosong jika tidak ada data.",
        "properties": {
          "overall_avg_seconds": {
            "type": "number",
            "description": "Rata-rata per sesi, satu desimal."
          },
          "overall_count": {
            "type": "integer",
            "description": "Sesi yang diukur."
          },
          "per_feature": {
            "type": "object",
            "description": "Menggunakan fitur sebagai kunci, misalnya `OCR` atau `LIVENESS`.",
            "additionalProperties": {
              "type": "object",
              "properties": {
                "avg_seconds": {
                  "type": "number"
                },
                "total_seconds": {
                  "type": "number"
                },
                "count": {
                  "type": "integer"
                }
              }
            }
          },
          "per_sub_step": {
            "type": "object",
            "description": "Menggunakan fitur sebagai kunci, lalu sub-langkah sebagai kunci berikutnya, misalnya `front_id_photo`.",
            "additionalProperties": {
              "type": "object",
              "additionalProperties": {
                "type": "object",
                "properties": {
                  "avg_seconds": {
                    "type": "number"
                  },
                  "total_seconds": {
                    "type": "number"
                  },
                  "count": {
                    "type": "integer"
                  }
                }
              }
            }
          }
        }
      },
      "ApplicationAnalyticsResubmissionStats": {
        "type": "object",
        "properties": {
          "first_pass": {
            "type": "integer",
            "description": "Sesi selesai tanpa pengajuan ulang."
          },
          "second": {
            "type": "integer",
            "description": "Sesi selesai yang diajukan ulang satu kali."
          },
          "third_plus": {
            "type": "integer",
            "description": "Sesi selesai yang diajukan ulang dua kali atau lebih."
          },
          "abandoned": {
            "type": "integer",
            "description": "Sesi yang ditinggalkan."
          }
        }
      },
      "ApplicationAnalyticsOriginalStatusStats": {
        "type": "object",
        "description": "Putusan otomatis alur kerja, sebelum peninjau mana pun mengubahnya.",
        "properties": {
          "approved": {
            "type": "integer"
          },
          "in_review": {
            "type": "integer"
          },
          "declined": {
            "type": "integer"
          }
        }
      },
      "ApplicationAnalyticsWarningStats": {
        "type": "object",
        "description": "Menggunakan fitur sebagai kunci (`ID_VERIFICATION`, `LIVENESS`, `FACEMATCH`, `AML`, `PROOF_OF_ADDRESS`, `PHONE`, `EMAIL`, `NFC`, `LOCATION`, `DATABASE_VALIDATION`, `QUESTIONNAIRE`, dan fitur-fitur KYB). `total` adalah sesi yang mencapai fitur tersebut; `risks` menghitung sesi per kode dan tingkat peringatan.",
        "additionalProperties": {
          "type": "object",
          "properties": {
            "total": {
              "type": "integer"
            },
            "risks": {
              "type": "object",
              "additionalProperties": {
                "type": "object",
                "properties": {
                  "error": {
                    "type": "integer"
                  },
                  "warning": {
                    "type": "integer"
                  },
                  "information": {
                    "type": "integer"
                  }
                }
              }
            }
          }
        }
      },
      "ApplicationAnalyticsDemographicPoint": {
        "type": "object",
        "properties": {
          "date": {
            "type": "string",
            "description": "Kunci periode: `YYYY-MM-DD` untuk hari, hari Senin dalam seminggu, atau `YYYY-MM` untuk bulan, mengikuti `grouping_mode`."
          },
          "age_distribution": {
            "type": "object",
            "additionalProperties": {
              "type": "integer"
            }
          },
          "gender_distribution": {
            "type": "object",
            "additionalProperties": {
              "type": "integer"
            }
          }
        }
      },
      "ApplicationAnalyticsDevicePoint": {
        "type": "object",
        "properties": {
          "date": {
            "type": "string",
            "description": "Kunci periode: `YYYY-MM-DD` untuk hari, hari Senin dalam seminggu, atau `YYYY-MM` untuk bulan, mengikuti `grouping_mode`."
          },
          "devices": {
            "type": "object",
            "additionalProperties": {
              "type": "integer"
            }
          },
          "browsers": {
            "type": "object",
            "additionalProperties": {
              "type": "integer"
            }
          },
          "operating_systems": {
            "type": "object",
            "additionalProperties": {
              "type": "integer"
            }
          }
        }
      },
      "ApplicationAnalyticsVerificationTimePoint": {
        "type": "object",
        "properties": {
          "date": {
            "type": "string",
            "description": "Kunci periode: `YYYY-MM-DD` untuk hari, hari Senin dalam seminggu, atau `YYYY-MM` untuk bulan, mengikuti `grouping_mode`."
          },
          "overall_avg": {
            "type": "number",
            "description": "Rata-rata detik aktif per sesi."
          },
          "per_feature": {
            "type": "object",
            "description": "Rata-rata detik aktif per fitur.",
            "additionalProperties": {
              "type": "number"
            }
          }
        }
      },
      "ApplicationAnalyticsResubmissionPoint": {
        "type": "object",
        "properties": {
          "date": {
            "type": "string",
            "description": "Kunci periode: `YYYY-MM-DD` untuk hari, hari Senin dalam seminggu, atau `YYYY-MM` untuk bulan, mengikuti `grouping_mode`."
          },
          "first_pass": {
            "type": "integer"
          },
          "second": {
            "type": "integer"
          },
          "third_plus": {
            "type": "integer"
          },
          "abandoned": {
            "type": "integer"
          }
        }
      },
      "ApplicationAnalyticsOriginalStatusPoint": {
        "type": "object",
        "properties": {
          "date": {
            "type": "string",
            "description": "Kunci periode: `YYYY-MM-DD` untuk hari, hari Senin dalam seminggu, atau `YYYY-MM` untuk bulan, mengikuti `grouping_mode`."
          },
          "approved": {
            "type": "integer"
          },
          "in_review": {
            "type": "integer"
          },
          "declined": {
            "type": "integer"
          }
        }
      },
      "ApplicationAnalyticsSummary": {
        "type": "object",
        "description": "Ringkasan verifikasi pengguna (KYC), dikembalikan saat `scope` maupun `widget_keys` tidak dikirim.",
        "required": [
          "data_points",
          "request_breakdown",
          "previous_data_points",
          "previous_request_breakdown",
          "conversion_rate",
          "location_stats",
          "demographic_stats",
          "device_details",
          "workflow_funnel_stats",
          "verification_time_stats",
          "resubmission_stats",
          "warning_stats",
          "original_status_stats",
          "grouping_mode",
          "demographic_time_series",
          "device_time_series",
          "verification_time_time_series",
          "resubmission_time_series",
          "original_status_time_series"
        ],
        "properties": {
          "data_points": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ApplicationAnalyticsDataPoint"
            },
            "description": "Satu titik per hari, dari hari pertama yang memiliki sesi dalam rentang tersebut hingga `end_date`. Selalu harian, apa pun nilai `grouping_mode`."
          },
          "request_breakdown": {
            "$ref": "#/components/schemas/ApplicationAnalyticsRequestBreakdown"
          },
          "previous_data_points": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ApplicationAnalyticsDataPoint"
            },
            "description": "Poin harian untuk periode dengan panjang yang sama tepat sebelum `start_date`."
          },
          "previous_request_breakdown": {
            "$ref": "#/components/schemas/ApplicationAnalyticsRequestBreakdown"
          },
          "conversion_rate": {
            "type": "number",
            "nullable": true,
            "description": "`total_approved / (total_approved + total_declined + total_in_review) x 100`, satu desimal. `null` saat belum ada yang selesai."
          },
          "location_stats": {
            "$ref": "#/components/schemas/ApplicationAnalyticsLocationStats"
          },
          "demographic_stats": {
            "$ref": "#/components/schemas/ApplicationAnalyticsDemographicStats"
          },
          "device_details": {
            "$ref": "#/components/schemas/ApplicationAnalyticsDeviceDetails"
          },
          "workflow_funnel_stats": {
            "$ref": "#/components/schemas/ApplicationAnalyticsWorkflowFunnel"
          },
          "verification_time_stats": {
            "$ref": "#/components/schemas/ApplicationAnalyticsVerificationTimeStats"
          },
          "resubmission_stats": {
            "$ref": "#/components/schemas/ApplicationAnalyticsResubmissionStats"
          },
          "warning_stats": {
            "$ref": "#/components/schemas/ApplicationAnalyticsWarningStats"
          },
          "original_status_stats": {
            "$ref": "#/components/schemas/ApplicationAnalyticsOriginalStatusStats"
          },
          "grouping_mode": {
            "type": "string",
            "enum": [
              "day",
              "week",
              "month"
            ],
            "description": "Bagaimana daftar `*_time_series` dikelompokkan: `day` untuk hingga 14 hari, `week` hingga 90, `month` untuk selebihnya. Diukur dari hari pertama yang memiliki sesi dalam rentang tersebut."
          },
          "demographic_time_series": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ApplicationAnalyticsDemographicPoint"
            }
          },
          "device_time_series": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ApplicationAnalyticsDevicePoint"
            }
          },
          "verification_time_time_series": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ApplicationAnalyticsVerificationTimePoint"
            }
          },
          "resubmission_time_series": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ApplicationAnalyticsResubmissionPoint"
            }
          },
          "original_status_time_series": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ApplicationAnalyticsOriginalStatusPoint"
            }
          }
        }
      },
      "ApplicationAnalyticsWidget": {
        "type": "object",
        "description": "Satu widget dasbor. Setiap widget memiliki `kind` dan `title`; kolom lainnya bergantung pada `kind`. Widget sesi menggunakan kembali objek ringkasan (`data_points`, `request_breakdown`, `workflow_funnel_stats`, dan seterusnya); widget daftar menempatkan entrinya di `items`; metrik transaksi menggunakan `value`.",
        "required": [
          "kind",
          "title"
        ],
        "properties": {
          "kind": {
            "type": "string",
            "enum": [
              "sessions_volume",
              "workflow_funnel",
              "average_verification_time",
              "country_distribution",
              "warning_insights",
              "conversion_rate",
              "conversion_by_country",
              "resubmission_insights",
              "original_status_distribution",
              "database_validation_coverage",
              "database_validation_latency",
              "demographics",
              "device_details",
              "horizontal_bar",
              "kyb_registry_coverage",
              "kyb_registry_data_completeness",
              "metric",
              "time_series",
              "breakdown",
              "status_time_series",
              "leaderboard",
              "histogram"
            ],
            "description": "Tipe widget."
          },
          "title": {
            "type": "string",
            "description": "Judul tampilan, misalnya `Verification volume`."
          },
          "grouping_mode": {
            "type": "string",
            "enum": [
              "day",
              "week",
              "month"
            ],
            "description": "Bagaimana daftar `*_time_series` dikelompokkan: `day` untuk hingga 14 hari, `week` hingga 90, `month` untuk selebihnya. Diukur dari hari pertama yang memiliki sesi dalam rentang tersebut."
          },
          "data_points": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ApplicationAnalyticsDataPoint"
            }
          },
          "request_breakdown": {
            "$ref": "#/components/schemas/ApplicationAnalyticsRequestBreakdown"
          },
          "previous_data_points": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ApplicationAnalyticsDataPoint"
            }
          },
          "previous_request_breakdown": {
            "$ref": "#/components/schemas/ApplicationAnalyticsRequestBreakdown"
          },
          "conversion_rate": {
            "type": "number",
            "nullable": true
          },
          "workflow_funnel_stats": {
            "$ref": "#/components/schemas/ApplicationAnalyticsWorkflowFunnel"
          },
          "verification_time_stats": {
            "$ref": "#/components/schemas/ApplicationAnalyticsVerificationTimeStats"
          },
          "verification_time_time_series": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ApplicationAnalyticsVerificationTimePoint"
            }
          },
          "warning_stats": {
            "$ref": "#/components/schemas/ApplicationAnalyticsWarningStats"
          },
          "resubmission_stats": {
            "$ref": "#/components/schemas/ApplicationAnalyticsResubmissionStats"
          },
          "resubmission_time_series": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ApplicationAnalyticsResubmissionPoint"
            }
          },
          "original_status_stats": {
            "$ref": "#/components/schemas/ApplicationAnalyticsOriginalStatusStats"
          },
          "original_status_time_series": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ApplicationAnalyticsOriginalStatusPoint"
            }
          },
          "demographic_stats": {
            "$ref": "#/components/schemas/ApplicationAnalyticsDemographicStats"
          },
          "demographic_time_series": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ApplicationAnalyticsDemographicPoint"
            }
          },
          "device_details": {
            "$ref": "#/components/schemas/ApplicationAnalyticsDeviceDetails"
          },
          "device_time_series": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ApplicationAnalyticsDevicePoint"
            }
          },
          "items": {
            "type": "array",
            "description": "Entri dari widget daftar. `country_distribution` (KYC): `country`, `country_code`, `session_count`. `conversion_by_country`: `country`, `country_code`, `finished`, `approved`. `time_series`: `date`, `value`. `status_time_series`: `date`, `approved`, `declined`, `flagged`. `breakdown`: `transaction_type` atau `action_type` dengan `count` dan `volume`, atau `tag_id`, `tag_name`, `count`. `leaderboard`: `rule_title`, `trigger_count` atau `assignee`, `handled_count`, `average_processing_seconds`, masing-masing dengan `approved_percentage`, `declined_percentage`, `flagged_percentage`. `histogram`: `score`, `count`.",
            "items": {
              "type": "object",
              "additionalProperties": {}
            }
          },
          "previous_items": {
            "type": "array",
            "description": "Rangkaian waktu transaksi untuk periode dengan panjang yang sama tepat sebelum `start_date`.",
            "items": {
              "type": "object",
              "additionalProperties": {}
            }
          },
          "value": {
            "type": "number",
            "description": "Widget `metric`: angka untuk rentang tersebut."
          },
          "currency": {
            "type": "string",
            "nullable": true,
            "description": "Widget volume dan jumlah transaksi: mata uang transaksi default aplikasi."
          },
          "thresholds": {
            "type": "object",
            "description": "Widget `histogram`: ambang batas skor peninjauan dan penolakan aplikasi.",
            "properties": {
              "review": {
                "type": "integer"
              },
              "decline": {
                "type": "integer"
              }
            }
          },
          "search": {
            "type": "object",
            "description": "Widget `kyb_registry_coverage`: total pencarian registri.",
            "properties": {
              "searches_total": {
                "type": "integer"
              },
              "searches_with_no_candidates": {
                "type": "integer"
              }
            }
          }
        }
      },
      "ApplicationAnalyticsWidgetResponse": {
        "type": "object",
        "description": "Widget dasbor, dikembalikan saat `scope` atau `widget_keys` dikirim.",
        "required": [
          "scope",
          "available_widget_keys",
          "requested_widget_keys",
          "widgets"
        ],
        "properties": {
          "scope": {
            "type": "string",
            "enum": [
              "home",
              "kyc",
              "kyb",
              "transactions"
            ],
            "description": "Tab dasbor."
          },
          "available_widget_keys": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Setiap kunci widget yang diterima oleh cakupan ini."
          },
          "requested_widget_keys": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Kunci widget yang dijawab, secara berurutan: `widget_keys` Anda yang valid, atau default dari cakupan tersebut."
          },
          "widgets": {
            "type": "object",
            "description": "Menggunakan kunci widget sebagai kunci, sesuai urutan `requested_widget_keys`.",
            "additionalProperties": {
              "$ref": "#/components/schemas/ApplicationAnalyticsWidget"
            }
          }
        }
      },
      "ApplicationAnalyticsToday": {
        "type": "object",
        "description": "Verifikasi hari ini berdasarkan jam lokal dibandingkan dengan hari yang sama minggu lalu.",
        "required": [
          "time_zone",
          "date",
          "current_hour",
          "previous_date",
          "hours",
          "previous_hours",
          "total",
          "previous_total_so_far",
          "outcomes"
        ],
        "properties": {
          "time_zone": {
            "type": "string",
            "description": "Zona waktu IANA tempat hari dan jam tersebut berlangsung.",
            "example": "Europe/Madrid"
          },
          "date": {
            "type": "string",
            "format": "date",
            "description": "Hari ini di zona waktu tersebut.",
            "example": "2026-10-30"
          },
          "current_hour": {
            "type": "integer",
            "minimum": 0,
            "maximum": 23,
            "description": "Jam lokal saat ini.",
            "example": 14
          },
          "previous_date": {
            "type": "string",
            "format": "date",
            "description": "Hari perbandingan: hari kerja yang sama satu minggu sebelumnya.",
            "example": "2026-10-23"
          },
          "hours": {
            "type": "array",
            "items": {
              "type": "integer",
              "minimum": 0
            },
            "minItems": 24,
            "maxItems": 24,
            "description": "Verifikasi yang dibuat hari ini, per jam lokal mulai pukul 00:00. Jam-jam yang belum terlewati bernilai 0."
          },
          "previous_hours": {
            "type": "array",
            "items": {
              "type": "integer",
              "minimum": 0
            },
            "minItems": 24,
            "maxItems": 24,
            "description": "Verifikasi yang dibuat pada hari pembanding, per jam lokal mulai pukul 00:00."
          },
          "total": {
            "type": "integer",
            "minimum": 0,
            "description": "Verifikasi yang dibuat hari ini sejauh ini.",
            "example": 165
          },
          "previous_total_so_far": {
            "type": "integer",
            "minimum": 0,
            "description": "Verifikasi yang dibuat pada hari pembanding hingga waktu lokal yang sama.",
            "example": 151
          },
          "outcomes": {
            "type": "object",
            "description": "Dari verifikasi hari ini, berapa banyak yang disetujui, menunggu dalam peninjauan, dan ditolak saat ini. Sisanya belum selesai.",
            "required": [
              "approved",
              "in_review",
              "declined"
            ],
            "properties": {
              "approved": {
                "type": "integer",
                "minimum": 0
              },
              "in_review": {
                "type": "integer",
                "minimum": 0
              },
              "declined": {
                "type": "integer",
                "minimum": 0
              }
            }
          }
        }
      },
      "WebhookConfigDestination": {
        "type": "object",
        "description": "Tujuan webhook sebagaimana tercantum dalam konfigurasi webhook, tanpa metrik pengiriman. `GET /v3/webhook/destinations/{destination_uuid}/` menambahkan ringkasan pengirimannya.",
        "required": [
          "uuid",
          "label",
          "url",
          "enabled",
          "webhook_version",
          "secret_shared_key",
          "subscribed_events",
          "created_at",
          "updated_at"
        ],
        "properties": {
          "uuid": {
            "type": "string",
            "format": "uuid",
            "description": "ID tujuan."
          },
          "label": {
            "type": "string",
            "maxLength": 255,
            "description": "Nama yang dapat dibaca manusia."
          },
          "url": {
            "type": "string",
            "format": "uri",
            "maxLength": 2000,
            "description": "Endpoint HTTPS tempat Didit mengirimkan event."
          },
          "enabled": {
            "type": "boolean",
            "description": "`false` menjeda pengiriman ke tujuan ini."
          },
          "webhook_version": {
            "type": "string",
            "enum": [
              "v1",
              "v2",
              "v3"
            ],
            "description": "Versi payload yang dikirim ke tujuan ini."
          },
          "secret_shared_key": {
            "type": "string",
            "description": "Rahasia penandatanganan tujuan ini (token 43 karakter yang aman untuk URL). Verifikasi setiap webhook dengan rahasia milik tujuan tempat webhook dikirimkan. Pemanggil dengan kunci API selalu menerimanya secara lengkap; pengguna Console tanpa `read:webhooks` akan menerima string kosong."
          },
          "subscribed_events": {
            "type": "array",
            "uniqueItems": true,
            "description": "Tipe event yang dikirimkan ke tujuan ini. Kosong jika tujuan dibuat tanpa event, yang dalam kasus ini tidak akan menerima apa pun.",
            "items": {
              "$ref": "#/components/schemas/WebhookEvent"
            }
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "WebhookConfig": {
        "type": "object",
        "description": "Konfigurasi webhook tingkat aplikasi, kebijakan retensi, dan host pengembalian dompet Digital ID, beserta setiap tujuan webhook.",
        "required": [
          "webhook_url",
          "webhook_version",
          "secret_shared_key",
          "capture_method",
          "data_retention_months",
          "face_retention_policy",
          "face_retention_days",
          "available_events",
          "allowed_return_hosts",
          "endpoints"
        ],
        "properties": {
          "webhook_url": {
            "type": "string",
            "format": "uri",
            "nullable": true,
            "description": "URL webhook tingkat aplikasi (lama). Didit hanya mengirim ke URL tersebut selama aplikasi tidak memiliki tujuan yang diaktifkan, dan setelah itu hanya `status.updated` dan `data.updated`. Setiap pembuatan, pembaruan, atau penghapusan tujuan akan menyetelnya ke URL tujuan aktif yang paling dahulu diaktifkan, atau `null` jika tidak ada yang diaktifkan."
          },
          "webhook_version": {
            "type": "string",
            "enum": [
              "v1",
              "v2",
              "v3"
            ],
            "description": "Versi payload dari `webhook_url` lama. Setiap tujuan memiliki `webhook_version` miliknya sendiri."
          },
          "secret_shared_key": {
            "type": "string",
            "description": "Rahasia penandatanganan tingkat aplikasi (token 43 karakter yang aman untuk URL). Ini hanya menandatangani pengiriman ke `webhook_url` lama; setiap tujuan menandatangani dengan `secret_shared_key` miliknya sendiri. Pemanggil yang menggunakan kunci API selalu menerimanya secara lengkap; pengguna Console tanpa `read:webhooks` menerima string kosong."
          },
          "capture_method": {
            "type": "string",
            "enum": [
              "MOBILE",
              "MOBILE_AND_DESKTOP"
            ],
            "description": "Pengaturan aplikasi lama. Alur verifikasi tidak membacanya: opsi pengambilan dikonfigurasi per alur kerja."
          },
          "data_retention_months": {
            "type": "integer",
            "nullable": true,
            "minimum": 1,
            "maximum": 120,
            "description": "Jendela penghapusan otomatis. Sesi verifikasi pengguna yang dibuat lebih dari sekian bulan lalu (satu bulan dihitung 30 hari) akan dihapus secara otomatis, dan penghapusan tersebut bersifat tidak dapat dibatalkan. `null` berarti sesi tidak pernah dihapus secara otomatis. Lihat [Retensi data](https://docs.didit.me/id/console/data-retention)."
          },
          "face_retention_policy": {
            "type": "string",
            "enum": [
              "delete_with_session",
              "retain_until_user_deleted"
            ],
            "description": "Hal yang terjadi pada embedding wajah sesi saat sesi dihapus. `delete_with_session` (default) menghapusnya bersama sesi. `retain_until_user_deleted` merupakan opsi [retensi templat biometrik](https://docs.didit.me/id/console/data-retention#retensi-templat-biometrik) yang dipilih secara sukarela: templat biometrik bebas gambar yang ditautkan ke Pengguna dikelola secara terpisah hingga periode retensinya berakhir, Pengguna dihapus, atau Anda menghapusnya secara permanen."
          },
          "face_retention_days": {
            "type": "integer",
            "nullable": true,
            "minimum": 1,
            "maximum": 3650,
            "description": "Periode retensi data, dalam hari, untuk templat biometrik di bawah `retain_until_user_deleted`. Wajib diisi jika kebijakan tersebut diatur."
          },
          "biometric_consent_mode": {
            "type": "string",
            "enum": [
              "auto",
              "always",
              "never"
            ],
            "description": "Kapan alur yang di-hosting dan SDK native meminta persetujuan biometrik eksplisit dari pengguna sebelum pengambilan wajah. `auto` (default) hanya meminta jika pemicu berlaku: negara bagian yang dinyatakan, IP pengguna, atau penerbit dokumen identitas berada di Illinois, Texas, atau Colorado, atau pengguna tampaknya berada di AS tanpa negara bagian yang diketahui. `always` meminta kepada setiap pengguna yang alur kerjanya mengambil gambar wajah. `never` tidak pernah menampilkan langkah tersebut, dan Anda mengumpulkan persetujuan sendiri sebelum swafoto. Setiap perubahan dicatat dalam log audit. Lihat [Persetujuan biometrik](https://docs.didit.me/id/getting-started/biometric-consent)."
          },
          "available_events": {
            "type": "array",
            "description": "Setiap tipe event yang dapat dilanggan oleh tujuan, dengan label tampilan.",
            "items": {
              "type": "object",
              "required": [
                "value",
                "label"
              ],
              "properties": {
                "value": {
                  "$ref": "#/components/schemas/WebhookEvent"
                },
                "label": {
                  "type": "string",
                  "description": "Label tampilan, misalnya `Session status updated`."
                }
              }
            }
          },
          "allowed_return_hosts": {
            "type": "array",
            "maxItems": 20,
            "description": "Nama host (kecocokan persis, hanya HTTPS) tempat verifikasi dompet Digital ID mandiri dapat mengarahkan pengguna kembali dengan `return_url`-nya. Domain White Label Anda juga selalu diizinkan. Lihat [Daftarkan tujuan pengembalian Anda](https://docs.didit.me/id/standalone-apis/digital-id-wallets#daftarkan-tujuan-pengembalian-anda).",
            "items": {
              "type": "string",
              "maxLength": 253
            }
          },
          "endpoints": {
            "type": "array",
            "description": "Setiap tujuan webhook dari aplikasi, yang terlama terlebih dahulu, masing-masing dengan rahasia penandatangannya. Hanya dapat dibaca di sini: kelola tujuan dengan endpoint `/v3/webhook/destinations/`.",
            "items": {
              "$ref": "#/components/schemas/WebhookConfigDestination"
            }
          },
          "allowed_domains": {
            "type": "array",
            "maxItems": 50,
            "items": {
              "type": "string",
              "maxLength": 300
            },
            "description": "Asal (misalnya `https://app.example.com`; `http` hanya untuk `localhost`) tempat alur verifikasi yang di-hosting dapat disematkan dan dapat mengarahkan pengguna kembali dengan callback sesi. Panggilan server-ke-server tidak terpengaruh. Daftar kosong berarti tidak ada batasan. Didit menyimpan setiap origin dalam huruf kecil tanpa port default. Entri yang tidak valid gagal dengan `400` pada `allowed_domains`.",
            "example": [
              "https://app.example.com"
            ]
          }
        }
      },
      "WebhookDestinationDelivery": {
        "type": "object",
        "description": "Satu upaya pengiriman ke tujuan webhook. Pengiriman pertama suatu event, setiap coba lagi otomatis, dan setiap pengiriman ulang merupakan pengiriman terpisah.",
        "required": [
          "uuid",
          "session_id",
          "request_url",
          "response_status",
          "response_time_ms",
          "status",
          "webhook_type",
          "created_at"
        ],
        "properties": {
          "uuid": {
            "type": "string",
            "format": "uuid",
            "description": "ID pengiriman, untuk panggilan guna melihat detail dan mengirim ulang."
          },
          "session_id": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "Sesi verifikasi pengguna yang terkait dengan event tersebut. `null` untuk event sesi bisnis, pengguna, bisnis, transaksi, Travel Rule, dan alur kerja."
          },
          "request_url": {
            "type": "string",
            "format": "uri",
            "nullable": true,
            "description": "URL tujuan pengiriman: URL tujuan saat event dibuat."
          },
          "response_status": {
            "type": "integer",
            "nullable": true,
            "description": "Status HTTP yang dikembalikan endpoint Anda. `null` saat pengiriman berada dalam antrean dan belum dicoba. Ketika tidak ada jawaban HTTP yang diterima, Didit mencatat statusnya sendiri: `504` ketika endpoint Anda tidak menjawab dalam 5 detik, `503` untuk kegagalan koneksi, `400` ketika URL ditolak karena tidak aman (misalnya alamat privat atau internal), dan `404` untuk kesalahan permintaan lainnya. `400` ke atas dihitung sebagai pengiriman gagal."
          },
          "response_time_ms": {
            "type": "integer",
            "nullable": true,
            "minimum": 0,
            "description": "Waktu yang dibutuhkan percobaan, dalam milidetik. `null` saat pengiriman sedang dalam antrean."
          },
          "status": {
            "type": "string",
            "nullable": true,
            "description": "Status yang dilaporkan event saat dibuat: status sesi untuk event sesi (misalnya `Approved` atau `In Review`), status individu atau perusahaan untuk event pengguna dan bisnis, serta status transaksi untuk event transaksi. `null` untuk event yang tidak membawa status."
          },
          "webhook_type": {
            "$ref": "#/components/schemas/WebhookEvent"
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "Waktu ketika pengiriman dibuat."
          }
        }
      },
      "WebhookDestinationDeliveryDetail": {
        "type": "object",
        "description": "Satu upaya pengiriman ke tujuan webhook, dengan header dan body permintaan persis seperti yang dikirimkan Didit.",
        "required": [
          "uuid",
          "session_id",
          "request_url",
          "response_status",
          "response_time_ms",
          "status",
          "webhook_type",
          "created_at",
          "request_header",
          "request_body"
        ],
        "properties": {
          "uuid": {
            "type": "string",
            "format": "uuid",
            "description": "ID pengiriman, untuk panggilan guna melihat detail dan mengirim ulang."
          },
          "session_id": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "Sesi verifikasi pengguna yang terkait dengan event tersebut. `null` untuk event sesi bisnis, pengguna, bisnis, transaksi, Travel Rule, dan alur kerja."
          },
          "request_url": {
            "type": "string",
            "format": "uri",
            "nullable": true,
            "description": "URL tujuan pengiriman: URL tujuan saat event dibuat."
          },
          "response_status": {
            "type": "integer",
            "nullable": true,
            "description": "Status HTTP yang dikembalikan endpoint Anda. `null` saat pengiriman berada dalam antrean dan belum dicoba. Ketika tidak ada jawaban HTTP yang diterima, Didit mencatat statusnya sendiri: `504` ketika endpoint Anda tidak menjawab dalam 5 detik, `503` untuk kegagalan koneksi, `400` ketika URL ditolak karena tidak aman (misalnya alamat privat atau internal), dan `404` untuk kesalahan permintaan lainnya. `400` ke atas dihitung sebagai pengiriman gagal."
          },
          "response_time_ms": {
            "type": "integer",
            "nullable": true,
            "minimum": 0,
            "description": "Waktu yang dibutuhkan percobaan, dalam milidetik. `null` saat pengiriman sedang dalam antrean."
          },
          "status": {
            "type": "string",
            "nullable": true,
            "description": "Status yang dilaporkan event saat dibuat: status sesi untuk event sesi (misalnya `Approved` atau `In Review`), status individu atau perusahaan untuk event pengguna dan bisnis, serta status transaksi untuk event transaksi. `null` untuk event yang tidak membawa status."
          },
          "webhook_type": {
            "$ref": "#/components/schemas/WebhookEvent"
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "Waktu ketika pengiriman dibuat."
          },
          "request_header": {
            "type": "string",
            "description": "Teks JSON (string) dari header permintaan yang dikirim Didit: `Content-Type`, `X-Signature`, `X-Signature-V2`, `X-Signature-Simple`, `X-Timestamp`, dan `User-Agent`. Parse teks ini dengan parser JSON. Teks ini memuat tanda tangan, tidak pernah rahasia penandatanganan."
          },
          "request_body": {
            "type": "string",
            "description": "Teks JSON (string) dari payload persis yang dikirim Didit, kunci diurutkan, termasuk `event_id` dan `timestamp`. Parse teks ini dengan parser JSON; lihat [Bentuk payload](https://docs.didit.me/id/integration/webhooks#struktur-payload). Untuk kunci dengan cakupan tanpa `media: read`, URL media di dalamnya bernilai `null`; tanpa `sessions: write`, token sesi dan tautan verifikasi yang di-hosting bernilai `null`. Body yang diubah dengan cara tersebut tidak lagi cocok dengan tanda tangannya. Didit tidak merekam body respons yang dikembalikan endpoint Anda."
          }
        }
      },
      "SessionWebhookDelivery": {
        "type": "object",
        "description": "Satu upaya pengiriman webhook yang dicatat untuk suatu sesi verifikasi, dengan header dan body permintaan yang persis dikirimkan oleh Didit.",
        "required": [
          "uuid",
          "session_id",
          "request_url",
          "response_status",
          "status",
          "webhook_type",
          "request_header",
          "request_body",
          "created_at"
        ],
        "properties": {
          "uuid": {
            "type": "string",
            "format": "uuid",
            "description": "ID pengiriman. Gunakan sebagai `{webhook_uuid}` untuk mengambil atau mengirim ulang pengiriman ini."
          },
          "session_id": {
            "type": "string",
            "format": "uuid",
            "description": "Sesi tempat pengiriman tersebut berada (sesi dalam jalur)."
          },
          "request_url": {
            "type": "string",
            "format": "uri",
            "nullable": true,
            "description": "URL tujuan pengiriman."
          },
          "response_status": {
            "type": "integer",
            "nullable": true,
            "description": "Status HTTP yang dikembalikan endpoint Anda. `null` saat pengiriman berada dalam antrean dan belum dicoba. Ketika tidak ada jawaban HTTP yang diterima, Didit mencatat statusnya sendiri: `504` ketika endpoint Anda tidak menjawab dalam 5 detik, `503` untuk kegagalan koneksi, `400` ketika URL ditolak karena tidak aman (misalnya alamat privat atau internal), dan `404` untuk kesalahan permintaan lainnya. `400` ke atas dihitung sebagai pengiriman gagal."
          },
          "status": {
            "type": "string",
            "nullable": true,
            "description": "Status sesi saat event dibuat, misalnya `In Progress`, `Approved`, atau `Declined`."
          },
          "webhook_type": {
            "$ref": "#/components/schemas/WebhookEvent"
          },
          "request_header": {
            "type": "string",
            "description": "Teks JSON (string) dari header permintaan yang dikirim Didit: `Content-Type`, `X-Signature`, `X-Signature-V2`, `X-Signature-Simple`, `X-Timestamp`, dan `User-Agent`. Parse teks ini dengan parser JSON. Teks ini memuat tanda tangan, tidak pernah rahasia penandatanganan."
          },
          "request_body": {
            "type": "string",
            "description": "Teks JSON (string) dari payload persis yang dikirim Didit, kunci diurutkan, termasuk `event_id` dan `timestamp`. Parse teks ini dengan parser JSON; lihat [Bentuk payload](https://docs.didit.me/id/integration/webhooks#struktur-payload). Untuk kunci dengan cakupan tanpa `media: read`, URL media di dalamnya bernilai `null`; tanpa `sessions: write`, token sesi dan tautan verifikasi yang di-hosting bernilai `null`. Body yang diubah dengan cara tersebut tidak lagi cocok dengan tanda tangannya. Didit tidak merekam body respons yang dikembalikan endpoint Anda."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "Waktu ketika pengiriman dibuat."
          }
        }
      },
      "SessionEvent": {
        "type": "object",
        "description": "Satu entri dari linimasa event sesi verifikasi.",
        "required": [
          "uuid",
          "event_type",
          "created_at",
          "component",
          "feature_step",
          "step",
          "details",
          "ip_address",
          "user_agent",
          "device_info",
          "file_url",
          "sent_at"
        ],
        "properties": {
          "uuid": {
            "type": "string",
            "format": "uuid",
            "description": "Pengenal event."
          },
          "event_type": {
            "type": "string",
            "enum": [
              "SESSION_CREATED",
              "SESSION_COMPLETED",
              "SESSION_STATUS_CHANGED",
              "LINK_OPENED",
              "FORM_SUBMITTED",
              "BUTTON_CLICKED",
              "FILE_UPLOADED",
              "ATTEMPT_FAILED",
              "FEATURE_STEP_CHANGED",
              "STEP_RENDERED",
              "NOTE_ADDED",
              "MANUAL_REVIEW_STARTED",
              "WORKFLOW_BRANCH_EVALUATED",
              "WORKFLOW_STATUS_NODE_REACHED",
              "LOG"
            ],
            "description": "Hal yang terjadi. Dilaporkan oleh perangkat selama alur yang di-hosting atau SDK: `LINK_OPENED`, `STEP_RENDERED`, `BUTTON_CLICKED`, `FORM_SUBMITTED`, `FILE_UPLOADED`, `ATTEMPT_FAILED`, dan `LOG` (debugging). Dicatat oleh server: `SESSION_CREATED`, `SESSION_STATUS_CHANGED` (`details.old_status`, `details.current_status`), `FEATURE_STEP_CHANGED` (`details.old_feature_step`, `details.current_feature_step`), `WORKFLOW_BRANCH_EVALUATED`, dan `WORKFLOW_STATUS_NODE_REACHED` (jejak perutean alur kerja). `SESSION_COMPLETED`, `NOTE_ADDED`, dan `MANUAL_REVIEW_STARTED` dapat muncul pada sesi yang lebih lama."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "Waktu ketika Didit menyimpan event tersebut. Event disimpan secara asinkron, beberapa detik setelah `sent_at`."
          },
          "component": {
            "type": "string",
            "nullable": true,
            "description": "Komponen antarmuka pengguna (UI) yang melaporkan event (hanya event perangkat)."
          },
          "feature_step": {
            "type": "string",
            "nullable": true,
            "enum": [
              "OCR",
              "OCR_BACK",
              "NFC",
              "AML",
              "FACE",
              "LIVENESS",
              "FACE_MATCH",
              "IP_ANALYSIS",
              "AGE_ESTIMATION",
              "PROOF_OF_ADDRESS",
              "PHONE_VERIFICATION",
              "EMAIL_VERIFICATION",
              "FACE_SEARCH",
              "DATABASE_VALIDATION",
              "QUESTIONNAIRE",
              "KYB_REGISTRY",
              "KYB_DOCUMENTS",
              "KYB_KEY_PEOPLE",
              "DOCUMENT_AI",
              "GEOLOCATION",
              null
            ],
            "description": "Fitur verifikasi yang sedang digunakan sesi saat event terjadi."
          },
          "step": {
            "type": "string",
            "nullable": true,
            "description": "Layar dalam fitur, misalnya `DOCUMENT_CAPTURE_FRONT` atau `FACE_PASSIVE_LIVENESS`."
          },
          "details": {
            "type": "object",
            "nullable": true,
            "additionalProperties": true,
            "description": "Data khusus event. Kuncinya bergantung pada `event_type`."
          },
          "ip_address": {
            "type": "string",
            "nullable": true,
            "description": "Alamat IP tempat perangkat melaporkan peristiwa. `null` untuk peristiwa yang dicatat oleh server."
          },
          "user_agent": {
            "type": "string",
            "nullable": true,
            "description": "User agent perangkat. `null` untuk event yang direkam server."
          },
          "device_info": {
            "type": "object",
            "nullable": true,
            "additionalProperties": true,
            "description": "Detail perangkat yang dilaporkan SDK atau browser."
          },
          "file_url": {
            "type": "string",
            "format": "uri",
            "nullable": true,
            "description": "Tautan presigned berdurasi singkat ke file yang dilampirkan pada event (misalnya gambar yang diambil). `null` jika tidak ada, dan selalu `null` untuk kunci API dengan cakupan terbatas tanpa `media: read`."
          },
          "sent_at": {
            "type": "integer",
            "format": "int64",
            "description": "Waktu ketika peristiwa terjadi, sebagai stempel waktu Unix dalam milidetik. Hasil diurutkan berdasarkan nilai ini."
          }
        }
      },
      "AMLDatasetSourceFreshness": {
        "type": "object",
        "description": "Kebaruan dari satu kelompok dataset AML.",
        "required": [
          "last_updated_at",
          "oldest_updated_at",
          "dataset_count",
          "dated_dataset_count"
        ],
        "properties": {
          "last_updated_at": {
            "type": "string",
            "format": "date-time",
            "description": "Pembaruan terbaru dari himpunan data apa pun dalam keluarga tersebut."
          },
          "oldest_updated_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Batas keusangan: setiap himpunan data dalam keluarga setidaknya semutakhir ini. `null` jika setidaknya satu himpunan data dalam keluarga tidak melaporkan tanggal pembaruan, karena batasnya menjadi tidak diketahui."
          },
          "dataset_count": {
            "type": "integer",
            "description": "Jumlah dataset dalam keluarga."
          },
          "dated_dataset_count": {
            "type": "integer",
            "description": "Jumlah himpunan data yang melaporkan tanggal pembaruan."
          }
        }
      },
      "AMLDatasetFreshness": {
        "type": "object",
        "description": "Tingkat kemutakhiran set data AML saat skrining dijalankan. Tanggal tidak pernah diestimasi.",
        "required": [
          "captured_at",
          "provider",
          "catalog_version",
          "sources"
        ],
        "properties": {
          "captured_at": {
            "type": "string",
            "format": "date-time",
            "description": "Waktu ketika Didit membaca katalog dataset yang menjadi sumber informasi kesegaran ini."
          },
          "provider": {
            "type": "string",
            "description": "Pengidentifikasi tidak transparan dari sumber data AML. Perlakukan sebagai string yang tidak transparan; jangan membuat percabangan logika berdasarkan nilai ini.",
            "example": "aml_data_source"
          },
          "catalog_version": {
            "type": "string",
            "nullable": true,
            "description": "Pengidentifikasi versi dari katalog dataset, jika sumber melaporkannya."
          },
          "sources": {
            "type": "object",
            "description": "Kebaruan per kelompok himpunan data. Kelompok yang himpunan datanya tidak melaporkan tanggal pembaruan tidak ditampilkan, alih-alih diisi dengan `null`.",
            "properties": {
              "sanctions": {
                "$ref": "#/components/schemas/AMLDatasetSourceFreshness"
              },
              "pep": {
                "$ref": "#/components/schemas/AMLDatasetSourceFreshness"
              },
              "warnings": {
                "$ref": "#/components/schemas/AMLDatasetSourceFreshness"
              },
              "adverse_media": {
                "$ref": "#/components/schemas/AMLDatasetSourceFreshness"
              }
            }
          }
        }
      },
      "AMLScreeningRun": {
        "type": "object",
        "description": "Satu skrining ulang pemantauan berkelanjutan yang telah selesai dari pemeriksaan AML.",
        "required": [
          "uuid",
          "run_id",
          "completed_at",
          "started_at",
          "outcome",
          "trigger",
          "provider",
          "status",
          "score",
          "total_hits",
          "new_hits",
          "entities_screened",
          "dataset_freshness"
        ],
        "properties": {
          "uuid": {
            "type": "string",
            "format": "uuid",
            "description": "Pengenal eksekusi skrining ini."
          },
          "run_id": {
            "type": "string",
            "format": "uuid",
            "description": "Putaran pemantauan tempat skrining ini berada. Setiap verifikasi yang diskrining dalam putaran yang sama memiliki nilai yang sama."
          },
          "completed_at": {
            "type": "string",
            "format": "date-time",
            "description": "Kapan skrining ulang subjek ini selesai. Hasil diurutkan berdasarkan ini, yang terbaru lebih dahulu."
          },
          "started_at": {
            "type": "string",
            "format": "date-time",
            "description": "Waktu batch pemantauan tempat skrining ulang ini berada dimulai."
          },
          "outcome": {
            "type": "string",
            "enum": [
              "NO_CHANGE",
              "CHANGED",
              "FAILED"
            ],
            "description": "`NO_CHANGE`: selesai dan hasilnya tidak berubah. `CHANGED`: selesai dan skor, status, jumlah kecocokan, atau kecocokan berubah. `FAILED`: tidak ada jawaban yang dapat digunakan untuk subjek ini, sehingga pemeriksaan dibiarkan apa adanya."
          },
          "trigger": {
            "type": "string",
            "enum": [
              "ONGOING_MONITORING"
            ],
            "description": "Apa yang memulai skrining. Selalu `ONGOING_MONITORING` saat ini."
          },
          "provider": {
            "type": "string",
            "description": "Pengidentifikasi opaque dari sumber data AML yang merespons. Perlakukan sebagai string opaque; jangan membuat percabangan logika berdasarkan nilai ini.",
            "example": "aml_data_source"
          },
          "status": {
            "type": "string",
            "nullable": true,
            "enum": [
              "Not Finished",
              "Approved",
              "Declined",
              "In Review",
              "Resub Requested",
              null
            ],
            "description": "Status pemeriksaan AML setelah eksekusi ini."
          },
          "score": {
            "type": "number",
            "format": "float",
            "nullable": true,
            "minimum": 0,
            "maximum": 100,
            "description": "Skor AML setelah eksekusi ini."
          },
          "total_hits": {
            "type": "integer",
            "nullable": true,
            "description": "Jumlah kecocokan yang tersisa dalam pemeriksaan setelah proses ini."
          },
          "new_hits": {
            "type": "integer",
            "nullable": true,
            "description": "Jumlah kecocokan yang ditemukan proses ini yang belum ada pada pemeriksaan sebelumnya. `0` ketika tidak ada hal baru yang ditemukan; `null` ketika proses gagal atau dicatat sebelum hitungan ini tersedia."
          },
          "entities_screened": {
            "type": "integer",
            "minimum": 0,
            "maximum": 1,
            "description": "Jumlah entitas yang diskrining oleh proses ini untuk verifikasi: `1` ketika subjek diskrining, `0` ketika proses gagal."
          },
          "dataset_freshness": {
            "allOf": [
              {
                "$ref": "#/components/schemas/AMLDatasetFreshness"
              }
            ],
            "nullable": true,
            "description": "Kebaruan himpunan data untuk proses ini, atau `null` jika tidak ada tanggal yang tersedia."
          }
        }
      },
      "KYBKeyPeopleParty": {
        "type": "object",
        "description": "Pihak dari pihak kunci pada sesi Verifikasi Bisnis (KYB), beserta verifikasi turunannya. Pihak yang sama muncul di `key_people_checks[].submitted.parties[]` dari keputusan sesi bisnis.",
        "required": [
          "uuid",
          "entity_type",
          "source",
          "name",
          "is_active",
          "is_skipped",
          "requires_verification",
          "roles",
          "kyc_session_deleted",
          "kyb_sub_session_deleted"
        ],
        "properties": {
          "uuid": {
            "type": "string",
            "format": "uuid",
            "description": "Pengidentifikasi pihak."
          },
          "entity_type": {
            "type": "string",
            "enum": [
              "person",
              "company"
            ],
            "description": "Apakah pihak tersebut adalah individu atau perusahaan."
          },
          "source": {
            "type": "string",
            "enum": [
              "REGISTRY",
              "USER"
            ],
            "description": "`REGISTRY`: diambil dari registri perusahaan. `USER`: dimasukkan di layar Key People."
          },
          "name": {
            "type": "string",
            "description": "Nama tampilan pihak."
          },
          "first_name": {
            "type": "string",
            "nullable": true,
            "description": "Nama depan (individu)."
          },
          "last_name": {
            "type": "string",
            "nullable": true,
            "description": "Nama belakang (individu)."
          },
          "company_name": {
            "type": "string",
            "nullable": true,
            "description": "Nama perusahaan (pihak perusahaan)."
          },
          "registration_number": {
            "type": "string",
            "nullable": true,
            "description": "Nomor registrasi perusahaan (pihak perusahaan)."
          },
          "email": {
            "type": "string",
            "format": "email",
            "nullable": true,
            "description": "Alamat email tujuan pengiriman tautan verifikasi."
          },
          "nationality": {
            "type": "string",
            "nullable": true,
            "description": "Kewarganegaraan untuk perorangan, negara pendirian untuk perusahaan."
          },
          "phone_number": {
            "type": "string",
            "nullable": true,
            "description": "Nomor telepon yang dikumpulkan untuk pihak tersebut."
          },
          "date_of_birth": {
            "type": "string",
            "format": "date",
            "nullable": true,
            "description": "Tanggal lahir (perorangan)."
          },
          "position": {
            "type": "string",
            "nullable": true,
            "description": "Jabatan berupa teks bebas (individu)."
          },
          "custom_fields": {
            "type": "object",
            "additionalProperties": true,
            "description": "Kolom kustom yang ditentukan alur kerja yang dikumpulkan untuk pihak tersebut, dengan kunci berupa kunci kolom."
          },
          "is_active": {
            "type": "boolean",
            "description": "Apakah pihak tersebut aktif."
          },
          "is_skipped": {
            "type": "boolean",
            "description": "Apakah pihak tersebut dikecualikan dari verifikasi. Pembuatan ulang akan menghapusnya."
          },
          "requires_verification": {
            "type": "boolean",
            "description": "Apakah aturan peran dan kepemilikan mewajibkan verifikasi untuk pihak ini."
          },
          "roles": {
            "type": "array",
            "description": "Peran yang dipegang pihak terkait di dalam perusahaan.",
            "items": {
              "type": "object",
              "required": [
                "role",
                "ownership_percent",
                "voting_percent"
              ],
              "properties": {
                "role": {
                  "type": "string",
                  "enum": [
                    "director",
                    "non_executive_director",
                    "secretary",
                    "chairman",
                    "ubo",
                    "shareholder",
                    "representative",
                    "founder",
                    "legal_advisor",
                    "authorized_signatory",
                    "trustee",
                    "beneficiary",
                    "settlor",
                    "protector",
                    "company_officer",
                    "investor",
                    "other"
                  ],
                  "description": "Kode peran."
                },
                "ownership_percent": {
                  "type": "number",
                  "nullable": true,
                  "description": "Persentase kepemilikan untuk peran ini, jika diketahui."
                },
                "voting_percent": {
                  "type": "number",
                  "nullable": true,
                  "description": "Persentase hak suara untuk peran ini, jika diketahui."
                }
              }
            }
          },
          "kyc_session_id": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "Sesi KYC individu turunan (perorangan)."
          },
          "kyc_session_status": {
            "type": "string",
            "nullable": true,
            "enum": [
              "Not Started",
              "In Progress",
              "Approved",
              "Declined",
              "In Review",
              "Expired",
              "Abandoned",
              "Kyc Expired",
              "Resubmitted",
              "Awaiting User",
              null
            ],
            "description": "Status sesi KYC turunan. Sesi yang dihapus tetap mempertahankan status yang dimilikinya saat dihapus."
          },
          "kyc_session_url": {
            "type": "string",
            "format": "uri",
            "nullable": true,
            "description": "Tautan yang di-hosting untuk sesi KYC turunan. `null` jika tidak ada atau telah dihapus, dan untuk kunci API yang dibatasi tanpa `sessions: write`."
          },
          "kyc_session_deleted": {
            "type": "boolean",
            "description": "Sesi KYC turunan telah dihapus, sehingga tidak akan pernah dapat diselesaikan."
          },
          "kyb_sub_session_id": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "Sesi KYB turunan (pihak perusahaan)."
          },
          "kyb_sub_session_status": {
            "type": "string",
            "nullable": true,
            "enum": [
              "Not Started",
              "In Progress",
              "Approved",
              "Declined",
              "In Review",
              "Expired",
              "Abandoned",
              "Kyc Expired",
              "Resubmitted",
              "Awaiting User",
              null
            ],
            "description": "Status sesi KYB turunan."
          },
          "kyb_sub_session_url": {
            "type": "string",
            "format": "uri",
            "nullable": true,
            "description": "Tautan yang di-hosting untuk sesi KYB turunan, dengan aturan `null` yang sama seperti `kyc_session_url`."
          },
          "kyb_sub_session_deleted": {
            "type": "boolean",
            "description": "Padanan pihak perusahaan untuk `kyc_session_deleted`."
          },
          "verification_workflow_type": {
            "type": "string",
            "nullable": true,
            "enum": [
              "kyc",
              "kyb",
              "adaptive_age_verification",
              "biometric_authentication",
              "address_verification",
              "questionnaire_verification",
              "email_verification",
              "phone_verification",
              null
            ],
            "description": "Jenis alur kerja yang dijalankan oleh sesi turunan."
          },
          "verification_workflow_id": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "Alur kerja yang dijalankan oleh sesi anak."
          },
          "verification_workflow_label": {
            "type": "string",
            "nullable": true,
            "description": "Label alur kerja tersebut."
          },
          "verification_workflow_features": {
            "type": "array",
            "nullable": true,
            "description": "Fitur dari alur kerja sesi turunan beserta statusnya saat ini.",
            "items": {
              "type": "object",
              "required": [
                "feature",
                "status"
              ],
              "properties": {
                "feature": {
                  "type": "string",
                  "description": "Kode fitur, misalnya `ID_VERIFICATION` atau `LIVENESS`."
                },
                "status": {
                  "type": "string",
                  "description": "Status fitur, `Not Finished` sampai fitur dijalankan."
                }
              }
            }
          },
          "didit_internal_id": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "Pengidentifikasi Didit untuk orang yang terverifikasi, setelah diketahui."
          }
        }
      },
      "TravelRuleDelivery": {
        "type": "object",
        "description": "Status pesan terbaru yang harus dikirimkan transfer ke pihak lain. Didit menghubungi pihak lawan setelah permintaan yang membuat atau mengubah transfer dikembalikan, sehingga objek ini menunjukkan apakah pesan tersebut berhasil terkirim: queued, being sent, waiting to be retried after an error, delivered, atau failed. Kegagalan yang masih dapat dipulihkan oleh jaringan (tidak ada jawaban tepat waktu, koneksi gagal, HTTP `408`, `429`, atau `5xx`) akan dicoba lagi setelah 30 detik, 2 menit, 10 menit, 30 menit, dan 1 jam. Saat pesan pertama (`kind: SEND`) gagal permanen, baik karena jaringan menolaknya atau percobaan keenam juga gagal, transfer berpindah ke `COUNTERPARTY_VASP_NOT_REACHABLE` dengan `last_error` di `timeline`-nya; pesan lain yang gagal permanen akan dicatat di `timeline`. `status` transfer tetap menjadi sumber kebenaran tunggal untuk pertukaran itu sendiri.",
        "required": [
          "kind",
          "status",
          "rail",
          "attempts",
          "last_error",
          "next_attempt_at",
          "delivered_at"
        ],
        "properties": {
          "kind": {
            "type": "string",
            "enum": [
              "SEND",
              "ANSWER",
              "TXID",
              "CANCEL",
              "POLL"
            ],
            "description": "Apa yang dibawa pesan. `SEND`: pesan pertama transfer ke pihak lawan (keluar; jalur pembayaran dipilih saat dikirim). `ANSWER`: persetujuan atau penolakan Anda, yang harus diberikan ke jaringan yang meminta (masuk). `TXID`: hash transaksi on-chain, setelah Anda menyelesaikan transfer. `CANCEL`: pembatalan, setelah Anda membatalkannya. `POLL`: kueri status ke jaringan yang menawarkannya, diulang setiap 5 menit saat transfer menunggu pihak lawan."
          },
          "status": {
            "type": "string",
            "enum": [
              "QUEUED",
              "SENDING",
              "RETRYING",
              "DELIVERED",
              "FAILED"
            ],
            "description": "`QUEUED`: menunggu untuk dikirim. `SENDING`: percobaan sedang berjalan. `RETRYING`: percobaan gagal dan percobaan berikutnya berjalan pada `next_attempt_at`. `DELIVERED`: pihak lain menerima pesan. `FAILED`: pihak lain menolaknya, atau percobaan terakhir gagal."
          },
          "rail": {
            "type": "string",
            "enum": [
              "INTERNAL",
              "TRP",
              "GTR",
              "TRUST",
              "VERIFYVASP",
              "SYGNA",
              "EMAIL",
              ""
            ],
            "description": "Jalur yang membawa pesan. Kosong hingga Didit memilih salah satu untuk pesan pertama."
          },
          "attempts": {
            "type": "integer",
            "minimum": 0,
            "description": "Percobaan yang dilakukan sejauh ini untuk pesan ini. Pesan yang bukan polling status dicoba paling banyak 6 kali."
          },
          "last_error": {
            "type": "string",
            "description": "Jenis kegagalan yang dialami pada upaya terakhir, `\"\"` jika tidak ada: misalnya `email undeliverable`, `trp identity endpoint unreachable`, atau `trp transfer inquiry delivery failed`. Kolom ini tidak pernah membawa jawaban pihak lawan itu sendiri, yang tetap berada di `timeline` transfer.\nKetika GTR merespons dengan kesalahan, kode status dan pesannya sendiri disertakan. Isi respons tidak pernah disertakan.",
            "example": "email undeliverable"
          },
          "next_attempt_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Waktu upaya berikutnya dijalankan saat pesan berstatus `QUEUED` atau `RETRYING`."
          },
          "delivered_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Waktu pihak lain menerima pesan."
          }
        }
      },
      "TravelRuleDiscoveryStep": {
        "type": "object",
        "description": "Satu langkah penemuan pihak lawan yang dijalankan Didit untuk transfer keluar, sesuai urutan eksekusinya. Langkah pertama yang menyebutkan VASP dengan rute akan mengakhiri rantai tersebut.",
        "properties": {
          "step": {
            "type": "string",
            "enum": [
              "internal_address_book",
              "wallet_attribution",
              "network_lookup",
              "customer_hint",
              "end_user"
            ],
            "description": "`internal_address_book`: pelanggan Didit lain yang membuktikan kontrol atas dompet tujuan. `wallet_attribution`: atribusi analitik blockchain dompet tersebut. `network_lookup`: jaringan yang dapat menyatakan VASP mana yang memegang alamat tersebut. `customer_hint`: nama VASP, LEI, atau yurisdiksi yang Anda kirimkan di `beneficiary_data`. `end_user`: pihak lawan yang dipilih oleh pengguna akhir (atau Anda), atau permintaan untuk memilih salah satunya."
          },
          "outcome": {
            "type": "string",
            "enum": [
              "match",
              "miss",
              "skipped"
            ],
            "description": "`match`: langkah tersebut menyebutkan pihak lawan. `miss`: langkah berjalan dan tidak menemukan apa pun. `skipped`: langkah tidak dapat berjalan, dan `reason` menjelaskan alasannya."
          },
          "reason": {
            "type": "string",
            "description": "Alasan yang dapat dibaca mesin, `\"\"` pada kecocokan: `no_proven_internal_wallet`, `attribution_disabled`, `already_attributed`, `no_attributed_entity`, `directory_match_no_route`, `gtr_address_lookup_runs_on_dispatch`, `no_membership`, `network_switched_off`, `no_network_address_lookup`, `no_directory_match`, `awaiting_end_user` atau `picked_member_without_proven_wallet`."
          },
          "vasp": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "VASP direktori yang disebutkan oleh langkah tersebut, jika ada."
          },
          "rail": {
            "type": "string",
            "nullable": true,
            "description": "Jalur yang menjangkau pihak lawan tersebut, ketika langkah menemukannya."
          },
          "at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "TravelRuleNextAction": {
        "type": "object",
        "description": "Satu hal yang melanjutkan transfer `COUNTERPARTY_VASP_NOT_FOUND` atau `COUNTERPARTY_VASP_NOT_REACHABLE`. Lihat [Mengapa transfer terhenti](/id/transaction-monitoring/travel-rule#mengapa-transfer-macet).",
        "properties": {
          "action": {
            "type": "string",
            "enum": [
              "select_counterparty_vasp",
              "declare_self_hosted",
              "add_vasp_hint",
              "update_compliance_email",
              "resend"
            ],
            "description": "`select_counterparty_vasp`: pengguna akhir memilih VASP tujuan di widget kepemilikan dompet, atau Anda melakukan PATCH `action=beneficiary_vasp`. `declare_self_hosted`: pengguna akhir menyatakan dompet tersebut swakelola di dalam widget. `add_vasp_hint`: beri tahu Didit siapa pihak lawannya, dengan nama VASP, LEI, atau Travel Address (misalnya `travel_address` pada entri buku alamat dompet tujuan), lalu kirim ulang. `update_compliance_email` dan `resend` adalah nilai `action` dari `PATCH /v3/transactions/{transaction_id}/travel-rule/`: berikan kembali email kepatuhan pihak lawan, dan jalankan perutean ulang."
          },
          "url": {
            "type": "string",
            "format": "uri",
            "description": "Tautan widget kepemilikan dompet, pada `select_counterparty_vasp` dan `declare_self_hosted` saat transfer memiliki sesi widget yang terbuka."
          }
        },
        "required": [
          "action"
        ]
      },
      "TransactionTravelRule": {
        "type": "object",
        "description": "Transfer Travel Rule dari transaksi, sebagaimana dikembalikan oleh `GET /v3/transactions/{transaction_id}/`, `201` dari `POST /v3/transactions/`, dan setiap baris dari `GET /v3/transactions/`. `direction`, `rail`, `counterparty_vasp`, `delivery`, `discovery`, `reason`, dan `next_actions` memiliki struktur yang sama seperti pada `PATCH /v3/transactions/{transaction_id}/travel-rule/`, sehingga satu kali pembacaan transaksi dapat menjelaskan alasan transfer tertahan dan tindakan apa yang dapat melanjutkannya.",
        "properties": {
          "uuid": {
            "type": "string",
            "format": "uuid"
          },
          "status": {
            "type": "string"
          },
          "protocol": {
            "type": "string",
            "nullable": true
          },
          "required": {
            "type": "boolean"
          },
          "obligations_count": {
            "type": "integer"
          },
          "originator_data": {
            "type": "object",
            "description": "Pihak pengirim. Untuk transfer masuk, nilai pihak lawan disamarkan sampai kepemilikan dikonfirmasi."
          },
          "beneficiary_data": {
            "type": "object",
            "description": "Pihak penerima. Untuk transfer masuk, nilai pihak lawan disamarkan hingga kepemilikan dikonfirmasi."
          },
          "name_match": {
            "type": "object",
            "nullable": true,
            "description": "Perbandingan nama yang menentukan transfer (skor dan tingkat ketatnya). Null hingga perbandingan dijalankan. Nama-nama yang dibandingkan disamarkan bersama dengan para pihak."
          },
          "data_match": {
            "$ref": "#/components/schemas/TravelRuleDataMatch"
          },
          "mismatched_fields": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Pintasan untuk `data_match.mismatched_fields`. Kosong jika tidak ada perbedaan."
          },
          "data_unmasked": {
            "$ref": "#/components/schemas/TravelRuleDataUnmasked"
          },
          "data_masked": {
            "type": "boolean",
            "description": "True selama data pribadi pihak lawan disamarkan dalam respons ini."
          },
          "metadata": {
            "type": "object"
          },
          "direction": {
            "type": "string",
            "enum": [
              "INBOUND",
              "OUTBOUND"
            ],
            "description": "Sisi pertukaran mana transfer ini berada."
          },
          "rail": {
            "type": "string",
            "nullable": true,
            "description": "Jalur yang dilalui transfer: `INTERNAL`, `TRP`, `GTR`, `TRUST`, `VERIFYVASP`, `SYGNA`, atau `EMAIL` (`TEST_VASP` pada aplikasi sandbox, saat Test VASP Didit merespons), atau `null` hingga sebuah jalur dipilih."
          },
          "counterparty_vasp": {
            "type": "object",
            "nullable": true,
            "properties": {
              "name": {
                "type": "string"
              },
              "lei": {
                "type": "string"
              },
              "dd_score": {
                "type": "integer",
                "description": "Skor uji tuntas dari 0 hingga 100, dengan nilai lebih tinggi lebih baik. Skala yang sama seperti dalam direktori VASP."
              },
              "dd_score_breakdown": {
                "type": "object",
                "description": "Kontribusi per komponen ke dd_score, satu objek per komponen seperti di direktori VASP (jurisdiction, verification, protocol, lei, history, essentials, responsiveness), masing-masing {points, max, reason, detail}. {} sampai pihak lawan telah dinilai.",
                "additionalProperties": {
                  "type": "object",
                  "properties": {
                    "points": {
                      "type": "number",
                      "description": "Poin yang diberikan untuk komponen ini."
                    },
                    "max": {
                      "type": "integer",
                      "description": "Poin maksimum yang dapat diberikan komponen ini."
                    },
                    "reason": {
                      "type": "string",
                      "description": "Kode yang dapat dibaca mesin untuk keputusan komponen."
                    },
                    "detail": {
                      "type": "string",
                      "description": "Alasan yang dapat dibaca manusia atas poin yang diberikan."
                    }
                  }
                }
              },
              "dd_assessed_at": {
                "type": "string",
                "format": "date-time",
                "nullable": true,
                "description": "Waktu ketika penilaian uji tuntas terakhir kali dijalankan. Null hingga pihak lawan telah dinilai."
              }
            },
            "description": "Entri direktori pihak lawan, atau `null` jika transfer tidak menautkan apa pun."
          },
          "delivery": {
            "nullable": true,
            "allOf": [
              {
                "$ref": "#/components/schemas/TravelRuleDelivery"
              }
            ],
            "description": "Pesan terbaru yang menjadi kewajiban transfer kepada pihak lain. `null` jika tidak ada kewajiban, misalnya di bawah `threshold_amount` atau untuk dompet swakelola yang dideklarasikan."
          },
          "discovery": {
            "type": "array",
            "description": "Cara Didit mencari pihak lawan, satu entri per langkah yang dijalankan. Kosong jika tidak ada penemuan yang dijalankan, misalnya pada transfer masuk.",
            "items": {
              "$ref": "#/components/schemas/TravelRuleDiscoveryStep"
            }
          },
          "reason": {
            "type": "string",
            "description": "Alasan transfer `COUNTERPARTY_VASP_NOT_FOUND` atau `COUNTERPARTY_VASP_NOT_REACHABLE` tertahan; `\"\"` untuk status lainnya. Pengiriman yang gagal menentukannya terlebih dahulu, hanya pada `COUNTERPARTY_VASP_NOT_REACHABLE`: `email_undeliverable` (penyedia email menolak email kepatuhan dan tidak ada alamat tersisa untuk dicoba: saat dikirim, pada pengingat, atau sebagai pantulan permanen yang dilaporkan kemudian) atau `delivery_failed` (jalur pengiriman gagal total: jalur jaringan menolak pesan atau kehabisan percobaan coba lagi, host identitas `TRP` tidak menjawab, atau host `TRP` pihak lawan tidak menerima permintaan informasi). Jika tidak, jejak `discovery` yang menentukannya: `awaiting_end_user` (tidak ada langkah yang menyebutkan pihak lawan yang dapat dijangkau Didit), `directory_match_no_route` (suatu langkah menyebutkan VASP direktori yang tidak memiliki rute), `picked_member_without_proven_wallet` (pengguna akhir memilih pelanggan Didit yang belum membuktikan kendali atas dompet), atau `no_directory_match` saat jejak tidak memberikan alasan lain. Pengiriman ulang akan memajukan transfer, sehingga alasannya dihapus. Lihat [Mengapa transfer tertahan](/id/transaction-monitoring/travel-rule#mengapa-transfer-macet)."
          },
          "next_actions": {
            "type": "array",
            "description": "Apa yang melanjutkan transfer; `[]` untuk status apa pun selain `COUNTERPARTY_VASP_NOT_FOUND` atau `COUNTERPARTY_VASP_NOT_REACHABLE`. `email_undeliverable` menawarkan `update_compliance_email`, lalu `resend`. `delivery_failed` menawarkan `resend`. Alasan penemuan menawarkan `select_counterparty_vasp`, `declare_self_hosted`, `add_vasp_hint`, dan `resend`.",
            "items": {
              "$ref": "#/components/schemas/TravelRuleNextAction"
            }
          },
          "chain_details": {
            "$ref": "#/components/schemas/TravelRuleChainDetails"
          }
        }
      },
      "NetworkListCounts": {
        "type": "object",
        "description": "Jumlah jaringan untuk tampilan dan opsi filter daftar, setiap jaringan dihitung sekali. Hanya dikembalikan jika `summary` bukan `false`. `scopes` menghitung setiap jaringan yang terlihat oleh aplikasi. `views` menghitung jaringan yang terlihat di dalam `scope` yang dipilih. `facets` menghitung jaringan di dalam `scope` yang dipilih dan tampilan `status` yang dipilih (jaringan yang diabaikan tidak disertakan kecuali `status` menyertakannya). Filter daftar lainnya tidak mengubah jumlah ini.",
        "properties": {
          "scopes": {
            "type": "object",
            "description": "Jaringan yang terlihat berdasarkan produk.",
            "properties": {
              "all": {
                "type": "integer"
              },
              "identity": {
                "type": "integer",
                "description": "Setiap jaringan lainnya."
              },
              "transactions": {
                "type": "integer",
                "description": "Jaringan yang semua anggotanya merupakan pihak transaksi."
              }
            }
          },
          "views": {
            "type": "object",
            "description": "Jaringan yang terlihat di dalam `scope` yang dipilih, berdasarkan status, ditambah dua tampilan tersimpan.",
            "properties": {
              "all": {
                "type": "integer"
              },
              "active": {
                "type": "integer"
              },
              "in_review": {
                "type": "integer"
              },
              "resolved": {
                "type": "integer"
              },
              "dismissed": {
                "type": "integer"
              },
              "mine": {
                "type": "integer",
                "description": "Jaringan yang ditugaskan ke anggota konsol yang melakukan pemanggilan. Selalu 0 untuk kunci API."
              },
              "high_risk": {
                "type": "integer",
                "description": "Jaringan dengan skor risiko 80 atau lebih yang tidak diabaikan."
              }
            }
          },
          "facets": {
            "type": "object",
            "description": "Jumlah untuk setiap opsi filter, di dalam `scope` dan tampilan status yang dipilih.",
            "properties": {
              "total": {
                "type": "integer",
                "description": "Jaringan dalam `scope` dan tampilan status yang dipilih."
              },
              "last_activity_days": {
                "type": "object",
                "description": "Jaringan dengan aktivitas dalam 7, 30, dan 90 hari terakhir, dikelompokkan berdasarkan jumlah hari.",
                "properties": {
                  "7": {
                    "type": "integer"
                  },
                  "30": {
                    "type": "integer"
                  },
                  "90": {
                    "type": "integer"
                  }
                }
              },
              "risk_min": {
                "type": "object",
                "description": "Jaringan dengan skor risiko minimal 50 dan minimal 80, dikelompokkan berdasarkan ambang batas.",
                "properties": {
                  "50": {
                    "type": "integer"
                  },
                  "80": {
                    "type": "integer"
                  }
                }
              },
              "signal_types": {
                "type": "object",
                "description": "Jaringan dengan setidaknya satu sinyal dari setiap jenis.",
                "properties": {
                  "ip_address": {
                    "type": "integer"
                  },
                  "device": {
                    "type": "integer"
                  },
                  "face": {
                    "type": "integer"
                  },
                  "document_number": {
                    "type": "integer"
                  },
                  "phone": {
                    "type": "integer"
                  },
                  "email": {
                    "type": "integer"
                  },
                  "address": {
                    "type": "integer"
                  }
                }
              },
              "priority": {
                "type": "object",
                "description": "Jaringan berdasarkan prioritas. `none` menghitung jaringan tanpa prioritas.",
                "properties": {
                  "low": {
                    "type": "integer"
                  },
                  "medium": {
                    "type": "integer"
                  },
                  "high": {
                    "type": "integer"
                  },
                  "none": {
                    "type": "integer"
                  }
                }
              },
              "assignee": {
                "type": "object",
                "description": "Jaringan berdasarkan penerima penugasan.",
                "properties": {
                  "me": {
                    "type": "integer",
                    "description": "Ditetapkan ke anggota konsol pemanggil. Selalu bernilai 0 untuk kunci API."
                  },
                  "unassigned": {
                    "type": "integer",
                    "description": "Tidak ditetapkan ke siapa pun."
                  },
                  "users": {
                    "type": "array",
                    "description": "Satu entri per penerima tugas, jaringan terbanyak terlebih dahulu.",
                    "items": {
                      "type": "object",
                      "properties": {
                        "uuid": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "full_name": {
                          "type": "string",
                          "description": "Nama penerima tugas, atau email mereka jika nama tidak diatur."
                        },
                        "email": {
                          "type": "string"
                        },
                        "count": {
                          "type": "integer"
                        }
                      }
                    }
                  }
                }
              },
              "has_case": {
                "type": "integer",
                "description": "Jaringan tempat aplikasi ini membuka kasus."
              },
              "min_size": {
                "type": "object",
                "description": "Jaringan dengan minimal 10 anggota, dikelompokkan berdasarkan ukuran minimum.",
                "properties": {
                  "10": {
                    "type": "integer"
                  }
                }
              }
            }
          }
        }
      },
      "NetworkTag": {
        "type": "object",
        "description": "Salah satu tag aplikasi Anda di jaringan.",
        "properties": {
          "uuid": {
            "type": "string",
            "format": "uuid",
            "description": "UUID tag, nilai yang sama dengan yang Anda kirimkan sebagai `tag_uuid`."
          },
          "name": {
            "type": "string"
          },
          "color": {
            "type": "string",
            "description": "Warna hex, misalnya `#6366F1`."
          },
          "source": {
            "type": "string",
            "enum": [
              "didit",
              "custom"
            ],
            "description": "`didit` untuk tag prasetel Didit, `custom` untuk tag yang dibuat tim Anda."
          },
          "added_by": {
            "type": "string",
            "nullable": true,
            "description": "Email anggota konsol yang menambahkan tag tersebut. Null jika ditambahkan oleh kunci API."
          },
          "added_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "NetworkOutcomes": {
        "type": "object",
        "description": "Status individu dan bisnis dalam jaringan. Setiap anggota yang dapat Anda lihat dihitung satu kali, berdasarkan status verifikasi terbaru mereka yang mencapai keputusan. Pihak transaksi tidak dihitung.",
        "properties": {
          "approved": {
            "type": "integer",
            "description": "Anggota yang verifikasi terbaru yang telah diputuskan berstatus disetujui."
          },
          "declined": {
            "type": "integer",
            "description": "Anggota yang verifikasi terbaru yang telah diputuskan berstatus ditolak."
          },
          "in_review": {
            "type": "integer",
            "description": "Anggota yang verifikasi terbaru yang telah diputuskan berada dalam peninjauan."
          },
          "total": {
            "type": "integer",
            "description": "Anggota dengan setidaknya satu verifikasi, baik yang telah diputuskan maupun belum. Anggota yang semua verifikasinya belum diputuskan (belum dimulai, sedang berlangsung, kedaluwarsa, atau ditinggalkan) dihitung di sini dan tidak pada kunci lainnya."
          }
        }
      },
      "NetworkPatternScore": {
        "type": "object",
        "description": "Tingkat kesamaan salah satu jenis data anggota di seluruh jaringan. Pola bukanlah sinyal: tidak ada nilai bersama yang menghubungkan para anggota.",
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "background"
            ],
            "description": "`background`: rerata kemiripan dari setiap pasangan latar belakang swafoto anggota, dengan orangnya disamarkan. Ini membaca swafoto terbaru dari setiap orang, paling banyak 50 swafoto terbaru, dan mengabaikan sesi verifikasi usia. Ini mencakup seluruh jaringan, tidak hanya anggota dari aplikasi Anda."
          },
          "score": {
            "type": "number",
            "nullable": true,
            "minimum": 0,
            "maximum": 1,
            "description": "Dari 0 hingga 1, dibulatkan ke 4 tempat desimal. Bernilai null saat `reason` diatur."
          },
          "members": {
            "type": "integer",
            "nullable": true,
            "description": "Berapa banyak swafoto anggota yang dibandingkan dalam penilaian. Swafoto yang tidak dapat dibaca, atau menampilkan latar belakang yang terlalu sedikit, tidak dibandingkan. Null selama `computing`; 0 atau 1 dengan `not_enough_selfies`."
          },
          "reason": {
            "type": "string",
            "enum": [
              "computing",
              "not_enough_selfies"
            ],
            "nullable": true,
            "description": "Alasan mengapa tidak ada skor. `computing`: skor untuk anggota saat ini sedang dihitung; kueri jaringan lagi nanti. `not_enough_selfies`: kurang dari dua anggota memiliki swafoto yang dapat digunakan. Null jika ada skor."
          },
          "computed_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Waktu skor dihitung. Null selama `computing`."
          }
        }
      },
      "NetworkDetailResponse": {
        "description": "Detail jaringan, ditambah mode berbagi organisasi, apakah sinyal lintas organisasi berlaku untuknya, tag aplikasi Anda di jaringan, hasil anggota, dan skor pola.",
        "allOf": [
          {
            "$ref": "#/components/schemas/NetworkDetail"
          },
          {
            "type": "object",
            "properties": {
              "sharing_mode": {
                "type": "string",
                "enum": [
                  "off",
                  "private",
                  "global"
                ],
                "description": "Mode berbagi lintas-organisasi milik organisasi. Hanya `global` yang membandingkan jaringan di seluruh organisasi; `private` dan `off` membatasinya hanya pada riwayat organisasi itu sendiri.",
                "example": "global"
              },
              "cross_org_available": {
                "type": "boolean",
                "description": "Menentukan apakah sinyal lintas organisasi berlaku untuk organisasi ini. Fitur ini memerlukan paket Enterprise dan mode berbagi `global`.",
                "example": true
              },
              "cross_org_unavailable_reason": {
                "type": "string",
                "enum": [
                  "plan",
                  "sharing_mode"
                ],
                "nullable": true,
                "description": "Alasan mengapa sinyal lintas organisasi tidak berlaku, diperiksa dalam urutan ini. `plan`: paket organisasi tidak mencakup jaringan penipuan lintas organisasi (memerlukan paket Enterprise), apa pun mode berbaginya. `sharing_mode`: paket mencakupnya, tetapi mode berbagi adalah `private` atau `off`. Null jika `cross_org_available` bernilai `true`.",
                "example": null
              },
              "tags": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/NetworkTag"
                },
                "description": "Tag aplikasi Anda di jaringan, yang terlama lebih dahulu. Setiap aplikasi hanya melihat tag miliknya sendiri. `fraud_tags` terpisah dan tidak berubah: tag yang dimiliki oleh anggota jaringan."
              },
              "outcomes": {
                "$ref": "#/components/schemas/NetworkOutcomes"
              },
              "patterns": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/NetworkPatternScore"
                },
                "description": "Skor pola di seluruh jaringan. Saat ini satu item, `background`."
              }
            }
          }
        ]
      },
      "NetworkTagRequest": {
        "type": "object",
        "required": [
          "tag_uuid"
        ],
        "properties": {
          "tag_uuid": {
            "type": "string",
            "format": "uuid",
            "description": "UUID dari salah satu tag aplikasi Anda."
          }
        },
        "example": {
          "tag_uuid": "7c9e6679-7425-40de-944b-e07fc1f90ae7"
        }
      },
      "NetworkTimeline": {
        "title": "Default timeline (no contract)",
        "type": "object",
        "description": "Tanpa `contract`: event milik jaringan itu sendiri, terlama lebih dulu, tanpa paginasi.",
        "properties": {
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/NetworkTimelineEvent"
            }
          }
        }
      },
      "NetworkTimelinePage": {
        "title": "Typed timeline page (contract=2)",
        "type": "object",
        "description": "Dengan `contract=2`: satu halaman event yang memiliki tipe, yang terbaru lebih dulu.",
        "properties": {
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/NetworkTypedTimelineEvent"
            }
          },
          "next_cursor": {
            "type": "string",
            "nullable": true,
            "description": "Teruskan sebagai `cursor` untuk membaca halaman berikutnya. Bernilai null pada halaman terakhir."
          }
        }
      },
      "NetworkTypedTimelineEvent": {
        "type": "object",
        "description": "Satu event timeline bertipe: empat kolom bawaan, ditambah id-nya, kapan Didit menyimpannya, akun anggota dan catatan tempat ia berada, serta blok detail dari tipe event-nya. Blok detail lainnya bernilai null.",
        "properties": {
          "id": {
            "type": "string",
            "description": "`<source>:<uuid>`, unik di dalam timeline.",
            "example": "session:3fa85f64-5717-4562-b3fc-2c963f66afa6"
          },
          "event_type": {
            "type": "string",
            "enum": [
              "network_detected",
              "signal_observed",
              "network_active",
              "network_in_review",
              "network_resolved",
              "network_dismissed",
              "verification_attempt",
              "transaction",
              "login",
              "rule_hit",
              "case_linked",
              "note_added"
            ]
          },
          "occurred_at": {
            "type": "string",
            "format": "date-time",
            "description": "Waktu terjadinya."
          },
          "ingested_at": {
            "type": "string",
            "format": "date-time",
            "description": "Waktu ketika Didit menyimpannya."
          },
          "label": {
            "type": "string",
            "description": "Label singkat berbahasa Inggris, misalnya `Verification attempt 2 of 3`."
          },
          "metadata": {
            "type": "object",
            "description": "Untuk event milik jaringan itu sendiri, metadata yang sama dengan linimasa default. Kosong jika tidak demikian."
          },
          "account": {
            "allOf": [
              {
                "$ref": "#/components/schemas/NetworkTimelineAccount"
              }
            ],
            "nullable": true,
            "description": "Akun anggota. Null untuk event milik jaringan itu sendiri, `case_linked` dan `note_added`."
          },
          "source_ref": {
            "allOf": [
              {
                "$ref": "#/components/schemas/NetworkTimelineSourceRef"
              }
            ],
            "nullable": true,
            "description": "Rekaman sumber. Null untuk event milik jaringan sendiri dan `note_added`."
          },
          "verification_attempt": {
            "allOf": [
              {
                "$ref": "#/components/schemas/NetworkTimelineAttempt"
              }
            ],
            "nullable": true,
            "description": "Ditetapkan pada event `verification_attempt`."
          },
          "transaction": {
            "allOf": [
              {
                "$ref": "#/components/schemas/NetworkTimelineTransaction"
              }
            ],
            "nullable": true,
            "description": "Ditetapkan pada event `transaction`."
          },
          "login": {
            "allOf": [
              {
                "$ref": "#/components/schemas/NetworkTimelineLogin"
              }
            ],
            "nullable": true,
            "description": "Ditetapkan pada event `login`."
          },
          "rule_hit": {
            "allOf": [
              {
                "$ref": "#/components/schemas/NetworkTimelineRuleHit"
              }
            ],
            "nullable": true,
            "description": "Ditetapkan pada event `rule_hit`."
          },
          "case_linked": {
            "allOf": [
              {
                "$ref": "#/components/schemas/NetworkTimelineCaseLinked"
              }
            ],
            "nullable": true,
            "description": "Ditetapkan pada event `case_linked`."
          },
          "note_added": {
            "allOf": [
              {
                "$ref": "#/components/schemas/NetworkTimelineNoteAdded"
              }
            ],
            "nullable": true,
            "description": "Ditetapkan pada event `note_added`. Tidak pernah dikembalikan ke kunci API."
          }
        }
      },
      "NetworkTimelineAccount": {
        "type": "object",
        "description": "Akun anggota pemilik event ini.",
        "properties": {
          "node_id": {
            "type": "string",
            "description": "`<kind>:<uuid>`, di mana jenisnya adalah `vendor_user`, `vendor_business`, atau `transaction_party`.",
            "example": "vendor_user:3fa85f64-5717-4562-b3fc-2c963f66afa6"
          },
          "node_type": {
            "type": "string",
            "enum": [
              "account",
              "business_account",
              "transaction_party"
            ]
          },
          "uuid": {
            "type": "string",
            "format": "uuid"
          },
          "vendor_data": {
            "type": "string",
            "nullable": true
          },
          "display_name": {
            "type": "string",
            "nullable": true
          },
          "ownership": {
            "type": "string",
            "enum": [
              "owned",
              "organization"
            ],
            "description": "`owned` saat data milik aplikasi yang Anda panggil (untuk anggota konsol, milik aplikasi yang diberikan izin kepadanya). `organization` saat milik aplikasi lain dari organisasi Anda."
          },
          "route": {
            "$ref": "#/components/schemas/NetworkTimelineRoute"
          }
        }
      },
      "NetworkTimelineSourceRef": {
        "type": "object",
        "description": "Rekaman tempat peristiwa dibaca.",
        "properties": {
          "kind": {
            "type": "string",
            "enum": [
              "session",
              "business_session",
              "transaction",
              "monitoring_event",
              "case"
            ]
          },
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "ownership": {
            "type": "string",
            "enum": [
              "owned",
              "organization"
            ],
            "description": "`owned` saat data milik aplikasi yang Anda panggil (untuk anggota konsol, milik aplikasi yang diberikan izin kepadanya). `organization` saat milik aplikasi lain dari organisasi Anda."
          },
          "route": {
            "allOf": [
              {
                "$ref": "#/components/schemas/NetworkTimelineRoute"
              }
            ],
            "description": "Tidak ada untuk `monitoring_event` dan `case`."
          }
        }
      },
      "NetworkTimelineRoute": {
        "type": "object",
        "description": "Tempat rekaman dibuka: jenisnya, UUID-nya, dan aplikasi pemiliknya.",
        "properties": {
          "kind": {
            "type": "string",
            "description": "`user`, `business`, atau `transaction_party` untuk sebuah akun; `session`, `business_session`, atau `transaction` untuk catatan sumber."
          },
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "application_id": {
            "type": "string",
            "format": "uuid"
          }
        }
      },
      "NetworkTimelineAttempt": {
        "type": "object",
        "description": "Satu sesi verifikasi dari akun tersebut.",
        "properties": {
          "session_id": {
            "type": "string",
            "format": "uuid",
            "description": "UUID sesi, atau UUID sesi bisnis untuk perusahaan."
          },
          "session_number": {
            "type": "integer",
            "nullable": true
          },
          "attempt": {
            "type": "integer",
            "description": "Posisi sesi ini di antara sesi akun, berdasarkan urutan pembuatan."
          },
          "attempt_count": {
            "type": "integer",
            "description": "Berapa banyak sesi yang dimiliki akun tersebut."
          },
          "status": {
            "type": "string",
            "description": "Status sesi, misalnya `Approved` atau `Declined`."
          },
          "status_changed_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "decline_reasons": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/NetworkTimelineDeclineReason"
            },
            "description": "Hanya untuk sesi yang ditolak: peringatannya, yang terlama terlebih dahulu, satu kali per peringatan. Kosong jika tidak demikian."
          }
        }
      },
      "NetworkTimelineDeclineReason": {
        "type": "object",
        "properties": {
          "risk": {
            "type": "string",
            "description": "Kode peringatan."
          },
          "feature": {
            "type": "string",
            "description": "Fitur yang memicu peringatan tersebut."
          },
          "short_description": {
            "type": "string"
          }
        }
      },
      "NetworkTimelineTransaction": {
        "type": "object",
        "description": "Transaksi yang diikuti oleh akun anggota, diberi tanggal berdasarkan tanggal transaksinya.",
        "properties": {
          "transaction_id": {
            "type": "string",
            "format": "uuid"
          },
          "transaction_number": {
            "type": "integer",
            "nullable": true
          },
          "transaction_type": {
            "type": "string"
          },
          "action_type": {
            "type": "string"
          },
          "amount": {
            "allOf": [
              {
                "$ref": "#/components/schemas/NetworkTimelineAmount"
              }
            ],
            "nullable": true,
            "description": "Null ketika transaksi tidak memiliki jumlah."
          },
          "status": {
            "type": "string"
          },
          "decision_reason_code": {
            "type": "string",
            "nullable": true
          },
          "decision_reason_label": {
            "type": "string",
            "nullable": true
          },
          "party_role": {
            "type": "string",
            "description": "Peran akun dalam transaksi: `APPLICANT`, `REMITTER`, `BENEFICIARY`, atau `COUNTERPARTY`."
          }
        }
      },
      "NetworkTimelineAmount": {
        "type": "object",
        "properties": {
          "value": {
            "type": "string",
            "description": "Jumlah desimal sebagai string."
          },
          "currency": {
            "type": "string"
          },
          "direction": {
            "type": "string",
            "nullable": true
          }
        }
      },
      "NetworkTimelineLogin": {
        "type": "object",
        "description": "Event masuk yang Anda kirimkan untuk seseorang melalui API event.",
        "properties": {
          "action": {
            "type": "string",
            "description": "`<event_category>.<action_type>`: `auth.login` atau `security.login_succeeded` untuk proses masuk, `auth.login_failed` atau `security.login_failed` jika gagal."
          },
          "succeeded": {
            "type": "boolean"
          },
          "status": {
            "type": "string",
            "description": "Status event."
          },
          "ip": {
            "allOf": [
              {
                "$ref": "#/components/schemas/NetworkTimelineIP"
              }
            ],
            "nullable": true,
            "description": "Null ketika event tidak memiliki alamat IP."
          },
          "device": {
            "allOf": [
              {
                "$ref": "#/components/schemas/NetworkTimelineDevice"
              }
            ],
            "nullable": true,
            "description": "Null ketika event tidak memiliki sidik jari perangkat atau konteks."
          },
          "is_first_login": {
            "type": "boolean",
            "description": "Waktu masuk pertama yang berhasil dari akun tersebut yang tercatat."
          },
          "is_new_device": {
            "type": "boolean",
            "description": "Proses masuk yang berhasil dari perangkat yang belum pernah digunakan untuk proses masuk yang berhasil sebelumnya pada akun tersebut. Tidak pernah bernilai true pada proses masuk pertama."
          }
        }
      },
      "NetworkTimelineIP": {
        "type": "object",
        "properties": {
          "address": {
            "type": "string"
          },
          "country_code": {
            "type": "string",
            "nullable": true
          },
          "city": {
            "type": "string",
            "nullable": true
          },
          "connection_type": {
            "type": "string",
            "nullable": true,
            "description": "Label jenis koneksi untuk alamat tersebut, sebagai teks bebas."
          },
          "is_vpn_or_tor": {
            "type": "boolean"
          },
          "is_data_center": {
            "type": "boolean"
          }
        }
      },
      "NetworkTimelineDevice": {
        "type": "object",
        "properties": {
          "fingerprint": {
            "type": "string",
            "nullable": true
          },
          "label": {
            "type": "string",
            "nullable": true,
            "description": "Label perangkat yang dapat dibaca yang dibuat dari konteks perangkat event."
          }
        }
      },
      "NetworkTimelineRuleHit": {
        "type": "object",
        "description": "Aturan live yang cocok dengan transaksi atau event anggota. Pencocokan mode uji tidak disertakan.",
        "properties": {
          "rule_id": {
            "type": "string",
            "format": "uuid"
          },
          "rule_title": {
            "type": "string"
          },
          "rule_category": {
            "type": "string"
          },
          "rule_source": {
            "type": "string"
          },
          "severity": {
            "type": "string",
            "nullable": true
          },
          "score_delta": {
            "type": "integer"
          },
          "status_target": {
            "type": "string",
            "nullable": true
          },
          "action_summary": {
            "type": "string",
            "nullable": true
          }
        }
      },
      "NetworkTimelineCaseLinked": {
        "type": "object",
        "description": "Kasus yang dibuka untuk jaringan di organisasi Anda. `source_ref.ownership` menyatakan apakah kasus tersebut milik aplikasi yang Anda panggil.",
        "properties": {
          "case_id": {
            "type": "string",
            "format": "uuid"
          },
          "case_number": {
            "type": "string",
            "nullable": true
          },
          "status": {
            "type": "string"
          },
          "author_email": {
            "type": "string",
            "nullable": true
          },
          "author_name": {
            "type": "string",
            "nullable": true
          }
        }
      },
      "NetworkTimelineNoteAdded": {
        "type": "object",
        "description": "Catatan yang ditinggalkan di jaringan. Teks catatan tidak disertakan.",
        "properties": {
          "note_id": {
            "type": "string",
            "format": "uuid"
          },
          "author_email": {
            "type": "string"
          }
        }
      },
      "FeatureStatusOverride": {
        "type": "object",
        "description": "Satu penimpaan status pemeriksaan (fitur) yang dibuat dengan `PATCH /v3/session/{sessionId}/features/{nodeId}/update-status/`: apa yang diubahnya, apakah sudah diterapkan atau masih menunggu orang tersebut menyelesaikan alur, siapa yang meminta dan alasannya.",
        "required": [
          "id",
          "node_id",
          "feature_type",
          "feature_model",
          "previous_status",
          "new_status",
          "state",
          "forced",
          "reason",
          "requested_by",
          "requested_at",
          "applied_at",
          "cancelled_at",
          "cancel_reason"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Pengenal penimpaan (override). Teruskan ke endpoint pembatalan.",
            "example": "7c9e6679-7425-40de-944b-e07fc1f90ae7"
          },
          "node_id": {
            "type": "string",
            "description": "Node alur kerja yang disebutkan dalam permintaan (`default` untuk langkah tanpa node).",
            "example": "feature_ocr_1"
          },
          "feature_type": {
            "type": "string",
            "description": "`feature_type` yang diteruskan oleh permintaan, atau string kosong jika tidak meneruskan apa pun.",
            "example": ""
          },
          "feature_model": {
            "type": "string",
            "description": "Jenis pemeriksaan yang ditimpa, misalnya `KYC`, `Face`, `AML`, atau `GeolocationCheck`.",
            "example": "KYC"
          },
          "previous_status": {
            "type": "string",
            "enum": [
              "Not Finished",
              "Approved",
              "Declined",
              "In Review",
              "Resub Requested"
            ],
            "description": "Status pemeriksaan saat override diminta.",
            "example": "In Review"
          },
          "new_status": {
            "type": "string",
            "enum": [
              "Approved",
              "Declined",
              "In Review"
            ],
            "description": "Status yang ditetapkan oleh penggantian (override).",
            "example": "Approved"
          },
          "state": {
            "type": "string",
            "enum": [
              "applied",
              "pending_until_flow_finishes",
              "cancelled"
            ],
            "description": "`applied`: pemeriksaan memiliki status baru. `pending_until_flow_finishes`: penggantian menunggu dan diterapkan saat orang tersebut menyelesaikan alur. `cancelled`: penggantian menunggu dan tidak pernah diterapkan (lihat `cancel_reason`).",
            "example": "applied"
          },
          "forced": {
            "type": "boolean",
            "description": "`true` saat penggantian diterapkan seketika saat orang tersebut masih berada dalam alur.",
            "example": false
          },
          "reason": {
            "type": "string",
            "nullable": true,
            "description": "`comment` yang dikirim bersama permintaan, atau `null`.",
            "example": "Document manually verified by compliance."
          },
          "requested_by": {
            "type": "object",
            "nullable": true,
            "description": "Pihak yang meminta override, atau `null` jika tidak diketahui.",
            "properties": {
              "email": {
                "type": "string",
                "format": "email",
                "nullable": true,
                "description": "Email pengguna konsol, atau `null` untuk kunci API dan sistem.",
                "example": "reviewer@example.com"
              },
              "name": {
                "type": "string",
                "nullable": true,
                "description": "Nama tampilan pemohon, atau `null`.",
                "example": "Alex Reviewer"
              },
              "type": {
                "type": "string",
                "enum": [
                  "CONSOLE_USER",
                  "API_KEY",
                  "SYSTEM"
                ],
                "description": "Pihak yang membuat permintaan: pengguna konsol, kunci API, atau Didit sendiri.",
                "example": "CONSOLE_USER"
              }
            }
          },
          "requested_at": {
            "type": "string",
            "format": "date-time",
            "description": "Waktu pengesampingan diminta.",
            "example": "2026-10-13T09:15:00Z"
          },
          "applied_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Waktu ketika pemeriksaan beralih ke status baru, atau `null` saat masih menunggu atau setelah dibatalkan.",
            "example": "2026-10-13T09:15:00Z"
          },
          "cancelled_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Saat penimpaan yang menunggu dibatalkan, atau `null`.",
            "example": null
          },
          "cancel_reason": {
            "type": "string",
            "nullable": true,
            "enum": [
              "cancelled_by_reviewer",
              "replaced",
              "check_changed",
              "session_closed",
              null
            ],
            "description": "Alasan mengapa override yang tertunda tidak pernah diterapkan, atau `null`. `cancelled_by_reviewer`: dibatalkan dengan endpoint pembatalan. `replaced`: digantikan oleh override yang lebih baru pada pemeriksaan yang sama. `check_changed`: pengguna mengulangi pemeriksaan sebelum menyelesaikan alur. `session_closed`: sesi meninggalkan alur sebelum pengguna menyelesaikannya (ditinggalkan, kedaluwarsa, atau diputuskan di tengah alur).",
            "example": null
          }
        }
      },
      "SandboxSimulateRequest": {
        "type": "object",
        "description": "Paksa status sesi sandbox. Setiap kolom bersifat opsional, tetapi setidaknya salah satu dari `new_status`, `scenario`, atau `risk` wajib diisi.",
        "properties": {
          "new_status": {
            "type": "string",
            "enum": [
              "Approved",
              "Declined",
              "In Review",
              "Expired",
              "Abandoned"
            ],
            "description": "Status yang akan ditetapkan. Jika Anda tidak menyertakannya, nilainya mengikuti status default kasus risiko (`risk`, atau risiko pertama yang dibawa oleh nilai ajaib skenario), jika tidak, kembali ke status default skenario.",
            "example": "Declined"
          },
          "comment": {
            "type": "string",
            "maxLength": 500,
            "description": "Catatan yang ditambahkan ke entri aktivitas yang mencatat perubahan status.",
            "example": "Testing the decline path"
          },
          "scenario": {
            "type": "string",
            "maxLength": 100,
            "description": "Slug skenario dari katalog (`GET /v1/sandbox/scenarios/`). Ini menyediakan status default dan, tanpa `risk`, peringatan yang dibawa oleh nilai ajaibnya. Slug yang tidak diketahui mengembalikan `400`.",
            "example": "decline_aml_hit"
          },
          "risk": {
            "type": "string",
            "maxLength": 128,
            "description": "Kasus risiko dari katalog. Peringatannya ditambahkan ke sesi, dengan tipe log yang mengikuti `new_status`. Nilai yang tidak diketahui mengembalikan `400`.",
            "example": "POSSIBLE_MATCH_FOUND"
          },
          "node_id": {
            "type": "string",
            "maxLength": 128,
            "description": "Node alur kerja tempat peringatan risiko ditautkan. Default-nya adalah node sesi saat ini.",
            "example": "feature_aml_1"
          },
          "send_webhooks": {
            "type": "boolean",
            "default": true,
            "description": "`true` mengirimkan tepat webhook yang dikirimkan oleh perubahan status riil ke tujuan aplikasi sandbox: `status.updated`, ditambah event `user.status.updated` / `user.data.updated` (atau `business.status.updated` / `business.data.updated`) yang ditimbulkan oleh perubahan tersebut, untuk tujuan yang berlangganan event tersebut. `false` mengubah status tanpa mencatat log atau mengirimkan webhook apa pun: pemulihan webhook yang terlewat tidak pernah mengirim ulang keputusan tersebut, dasbor tetap diperbarui secara langsung, dan perubahan status berikutnya dari sesi tersebut akan mengirimkan webhook seperti biasa.",
            "example": true
          }
        }
      },
      "SandboxSimulateResponse": {
        "type": "object",
        "required": [
          "session_id",
          "previous_status",
          "status",
          "scenario",
          "risk",
          "send_webhooks"
        ],
        "properties": {
          "session_id": {
            "type": "string",
            "format": "uuid",
            "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
          },
          "previous_status": {
            "type": "string",
            "enum": [
              "Not Started",
              "In Progress",
              "Approved",
              "Declined",
              "In Review",
              "Expired",
              "Abandoned",
              "Kyc Expired",
              "Resubmitted",
              "Awaiting User"
            ],
            "description": "Status sesi sebelum simulasi.",
            "example": "In Progress"
          },
          "status": {
            "type": "string",
            "enum": [
              "Approved",
              "Declined",
              "In Review",
              "Expired",
              "Abandoned"
            ],
            "description": "Status yang ditetapkan oleh simulasi.",
            "example": "Declined"
          },
          "scenario": {
            "type": "string",
            "nullable": true,
            "description": "Slug skenario yang Anda teruskan, atau `null`.",
            "example": "decline_aml_hit"
          },
          "risk": {
            "type": "string",
            "nullable": true,
            "description": "Kasus risiko yang diterapkan (`risk`, atau kasus yang diambil dari skenario), atau `null` jika tidak ada.",
            "example": "POSSIBLE_MATCH_FOUND"
          },
          "send_webhooks": {
            "type": "boolean",
            "description": "Nilai `send_webhooks` yang diterapkan oleh simulasi.",
            "example": false
          }
        }
      },
      "CaseTeamSummary": {
        "type": "object",
        "nullable": true,
        "description": "Tim peninjau yang memiliki kasus tersebut, atau null jika tidak ada tim yang memilikinya. Perutean menetapkannya ketika aturan perutean menempatkan kasus tersebut ke salah satu timnya. Ubah atau hapus dengan `PATCH .../cases/{case_uuid}/` (`team`).",
        "properties": {
          "uuid": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          }
        }
      },
      "CaseChecker": {
        "type": "object",
        "nullable": true,
        "description": "Anggota yang ditunjuk untuk menyetujui atau menolak resolusi yang tertunda. Hanya ditetapkan saat resolusi dengan pemeriksaan empat mata sedang menunggu pemeriksa yang ditunjuk. Null jika tidak ada yang tertunda, saat resolusi yang tertunda menunggu di antrean pemeriksa, dan setelah resolusi disetujui, ditolak, atau dikembalikan untuk peninjauan baru karena bukti berubah.",
        "properties": {
          "member_uuid": {
            "type": "string",
            "format": "uuid",
            "description": "UUID pengguna anggota: nilai yang Anda kirimkan sebagai `checker` saat Anda menyelesaikan kasus."
          },
          "name": {
            "type": "string",
            "nullable": true,
            "description": "Nama lengkap anggota, atau null jika tidak diketahui."
          },
          "email": {
            "type": "string",
            "format": "email"
          }
        }
      },
      "ServiceStatusFeed": {
        "type": "object",
        "description": "Status layanan publik: status setiap layanan Didit, status keseluruhan, dan insiden yang sedang berlangsung atau telah diselesaikan dalam 7 hari terakhir.",
        "required": [
          "status",
          "updated_at",
          "services",
          "incidents"
        ],
        "properties": {
          "status": {
            "type": "string",
            "enum": [
              "operational",
              "degraded",
              "down"
            ],
            "description": "Status terburuk dari layanan apa pun saat ini, ditentukan hanya berdasarkan insiden yang sedang berlangsung.",
            "example": "degraded"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time",
            "description": "Waktu ketika Didit membuat respons ini (ISO 8601, UTC). Respons di-cache selama 30 detik, sehingga usianya bisa mencapai 30 detik.",
            "example": "2026-10-13T09:41:07.512345Z"
          },
          "services": {
            "type": "array",
            "description": "Satu entri per layanan, setiap layanan selalu dicantumkan.",
            "items": {
              "$ref": "#/components/schemas/ServiceStatusService"
            }
          },
          "incidents": {
            "type": "array",
            "description": "`started_at` terbaru terlebih dahulu. Setiap insiden yang sedang berlangsung, ditambah insiden yang diselesaikan dalam 7 hari terakhir (maksimal 50 insiden yang diselesaikan). Kosong jika tidak ada yang terjadi dalam kurun waktu tersebut.",
            "items": {
              "$ref": "#/components/schemas/ServiceStatusIncident"
            }
          }
        }
      },
      "ServiceStatusService": {
        "type": "object",
        "required": [
          "key",
          "name",
          "status"
        ],
        "properties": {
          "key": {
            "type": "string",
            "enum": [
              "service_id_verification",
              "service_liveness_face_match",
              "service_aml_screening",
              "service_kyb_registries",
              "service_database_validation",
              "service_phone_delivery",
              "service_email_delivery",
              "service_transaction_monitoring"
            ],
            "description": "Kunci layanan yang stabil. Cocokkan berdasarkan ini, jangan pernah berdasarkan nama tampilan. `service_id_verification`: Verifikasi Identitas, `service_liveness_face_match`: Deteksi Liveness dan Pencocokan Wajah, `service_aml_screening`: Skrining AML, `service_kyb_registries`: Registri KYB, `service_database_validation`: Validasi Database, `service_phone_delivery`: Pengiriman Verifikasi Telepon, `service_email_delivery`: Pengiriman Verifikasi Email, `service_transaction_monitoring`: Pemantauan Transaksi.",
            "example": "service_database_validation"
          },
          "name": {
            "type": "string",
            "description": "Nama tampilan berbahasa Inggris untuk layanan tersebut.",
            "example": "Database validation"
          },
          "status": {
            "type": "string",
            "enum": [
              "operational",
              "degraded",
              "down"
            ],
            "description": "`operational` saat tidak ada insiden yang sedang berlangsung untuk layanan tersebut, jika tidak maka merupakan status terburuk dari insiden yang sedang berlangsung.",
            "example": "degraded"
          }
        }
      },
      "ServiceStatusIncident": {
        "type": "object",
        "required": [
          "id",
          "service",
          "service_name",
          "state",
          "status",
          "title",
          "body",
          "affected",
          "country_name",
          "started_at",
          "resolved_at",
          "duration_minutes"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "ID insiden.",
            "example": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
          },
          "service": {
            "type": "string",
            "enum": [
              "service_id_verification",
              "service_liveness_face_match",
              "service_aml_screening",
              "service_kyb_registries",
              "service_database_validation",
              "service_phone_delivery",
              "service_email_delivery",
              "service_transaction_monitoring"
            ],
            "description": "Kunci dari layanan yang terpengaruh (lihat `services[].key`).",
            "example": "service_database_validation"
          },
          "service_name": {
            "type": "string",
            "description": "Nama tampilan berbahasa Inggris untuk layanan yang terpengaruh.",
            "example": "Database validation"
          },
          "state": {
            "type": "string",
            "enum": [
              "degraded",
              "down"
            ],
            "description": "Bagaimana layanan terpengaruh. Insiden yang terselesaikan mempertahankan status terakhir yang dimilikinya.",
            "example": "degraded"
          },
          "status": {
            "type": "string",
            "enum": [
              "ongoing",
              "resolved"
            ],
            "description": "`ongoing` hingga layanan pulih, kemudian `resolved`.",
            "example": "ongoing"
          },
          "title": {
            "type": "string",
            "description": "Judul berbahasa Inggris. Untuk menerjemahkannya, buat teks Anda sendiri dari `service`, `state`, dan `country_name`.",
            "example": "Database validation is degraded in Brazil."
          },
          "body": {
            "type": "string",
            "description": "Baris detail berbahasa Inggris: sejak kapan pemeriksaan mungkin lambat atau gagal, atau kapan pemeriksaan pulih.",
            "example": "Checks against Brazil (CPF) may be slow or fail since 08:55 UTC."
          },
          "affected": {
            "type": "string",
            "description": "Negara atau registri yang terdampak, misalnya `Brazil (CPF)`. Kosong jika insiden tidak terkait dengan negara atau registri.",
            "example": "Brazil (CPF)"
          },
          "country_name": {
            "type": "string",
            "description": "Negara yang terdampak, dalam bahasa Inggris. Kosong jika insiden tidak terkait dengan suatu negara.",
            "example": "Brazil"
          },
          "started_at": {
            "type": "string",
            "format": "date-time",
            "description": "Waktu insiden dimulai (ISO 8601, UTC).",
            "example": "2026-10-13T08:55:00Z"
          },
          "resolved_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Waktu layanan pulih (ISO 8601, UTC). `null` selama insiden masih berlangsung."
          },
          "duration_minutes": {
            "type": "integer",
            "nullable": true,
            "description": "Menit penuh dari `started_at` hingga `resolved_at`. `null` selama insiden masih berlangsung."
          }
        }
      },
      "TravelRuleJoinInvitation": {
        "type": "object",
        "description": "Apa yang ditampilkan halaman untuk bergabung sebelum apa pun diketik.",
        "properties": {
          "email": {
            "type": "string",
            "format": "email",
            "description": "Alamat tujuan pengiriman undangan."
          },
          "vasp_name": {
            "type": "string"
          },
          "source": {
            "type": "string",
            "description": "Dari mana undangan tersebut berasal, misalnya `pickup`."
          },
          "expires_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "prefill": {
            "type": "object",
            "properties": {
              "vasp_id": {
                "type": "string",
                "format": "uuid",
                "nullable": true
              },
              "legal_name": {
                "type": "string"
              },
              "lei": {
                "type": "string"
              },
              "jurisdiction": {
                "type": "string"
              },
              "domains": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              }
            }
          }
        }
      },
      "TravelRuleJoinRegisterRequest": {
        "type": "object",
        "required": [
          "email",
          "password"
        ],
        "properties": {
          "email": {
            "type": "string",
            "format": "email",
            "maxLength": 254,
            "description": "Harus berupa alamat tujuan pengiriman undangan."
          },
          "password": {
            "type": "string",
            "minLength": 8,
            "maxLength": 128
          }
        }
      },
      "TravelRuleJoinVerifyRequest": {
        "type": "object",
        "required": [
          "email",
          "code"
        ],
        "properties": {
          "email": {
            "type": "string",
            "format": "email",
            "maxLength": 254
          },
          "code": {
            "type": "string",
            "minLength": 6,
            "maxLength": 6,
            "description": "Kode 6 karakter yang dikirim melalui email setelah mendaftar."
          }
        }
      },
      "TravelRuleJoinCredentials": {
        "type": "object",
        "description": "Organisasi gratis baru dan kredensial yang digunakan aplikasinya untuk memanggil API.",
        "properties": {
          "organization": {
            "type": "object",
            "properties": {
              "uuid": {
                "type": "string",
                "format": "uuid"
              }
            }
          },
          "application": {
            "type": "object",
            "properties": {
              "uuid": {
                "type": "string",
                "format": "uuid"
              }
            }
          },
          "client_id": {
            "type": "string"
          },
          "api_key": {
            "type": "string",
            "description": "Kirim sebagai header `x-api-key` pada endpoint ruang kerja."
          }
        }
      },
      "TravelRuleWorkspaceClaimRequest": {
        "type": "object",
        "required": [
          "vasp_id"
        ],
        "properties": {
          "vasp_id": {
            "type": "string",
            "format": "uuid",
            "description": "Entri direktori dari ruang kerja ini. Baca ID dari `GET /v3/travel-rule/vasps/`."
          }
        }
      },
      "TravelRuleWorkspaceDomainConfirmRequest": {
        "type": "object",
        "required": [
          "code"
        ],
        "properties": {
          "code": {
            "type": "string",
            "minLength": 6,
            "maxLength": 6
          }
        }
      },
      "TravelRuleWorkspaceBillingRequest": {
        "type": "object",
        "properties": {
          "enabled": {
            "type": "boolean",
            "default": true,
            "description": "Hanya `true` yang diterima: penagihan keluar tidak dapat dimatikan kembali melalui API."
          }
        }
      },
      "TravelRuleWorkspaceDomainCodeResponse": {
        "type": "object",
        "properties": {
          "domain": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "unverified",
              "code_sent",
              "verified"
            ]
          },
          "txt": {
            "$ref": "#/components/schemas/TravelRuleWorkspaceTxtRecord"
          }
        }
      },
      "TravelRuleWorkspaceTxtRecord": {
        "type": "object",
        "description": "Record TXT yang akan dipublikasikan untuk bukti DNS. Kosong hingga pembuktian dimulai.",
        "properties": {
          "host": {
            "type": "string",
            "example": "didit-tr-verify.example.com"
          },
          "value": {
            "type": "string"
          }
        }
      },
      "TravelRuleWorkspace": {
        "type": "object",
        "description": "Ruang kerja Travel Rule gratis dari aplikasi yang bergabung secara gratis.",
        "properties": {
          "joined_free": {
            "type": "boolean"
          },
          "work_email": {
            "type": "string",
            "format": "email"
          },
          "joined_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "claim": {
            "type": "object",
            "properties": {
              "status": {
                "type": "string",
                "enum": [
                  "unclaimed",
                  "pending_review",
                  "claimed",
                  "rejected"
                ]
              },
              "proved_by_domain": {
                "type": "boolean"
              },
              "claimed_at": {
                "type": "string",
                "format": "date-time",
                "nullable": true
              },
              "reviewed_at": {
                "type": "string",
                "format": "date-time",
                "nullable": true
              },
              "review_note": {
                "type": "string"
              },
              "vasp_id": {
                "type": "string",
                "format": "uuid",
                "nullable": true
              },
              "vasp_name": {
                "type": "string"
              }
            }
          },
          "prefill": {
            "type": "object",
            "description": "Nilai profil yang diambil dari entri direktori: `vasp_id`, `legal_name`, `lei`, `jurisdiction`, `compliance_email`, `domains`. Tidak ada yang ditulis hingga klaim dibuat."
          },
          "domain": {
            "type": "object",
            "properties": {
              "domain": {
                "type": "string"
              },
              "status": {
                "type": "string",
                "enum": [
                  "unverified",
                  "code_sent",
                  "verified"
                ]
              },
              "verified_at": {
                "type": "string",
                "format": "date-time",
                "nullable": true
              },
              "txt": {
                "$ref": "#/components/schemas/TravelRuleWorkspaceTxtRecord"
              }
            }
          },
          "billing_enabled": {
            "type": "boolean",
            "description": "Menerima data Travel Rule gratis. Pengiriman hanya ditagih setelah penagihan diaktifkan."
          },
          "billing_enabled_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "didit_network": {
            "type": "object",
            "description": "Menentukan apakah jaringan Didit mencantumkan VASP ini dan, jika tidak, setiap kondisi yang masih belum terpenuhi."
          },
          "settings": {
            "$ref": "#/components/schemas/TravelRuleSettingsDetail"
          }
        }
      },
      "InvestigatorDecision": {
        "type": "object",
        "description": "Bagaimana item meninggalkan antrean Investigator. `decided_by`, `original_outcome`, dan `overrides` dikembalikan oleh endpoint accept dan override serta laporan; blok `investigator` pada keputusan sesi memuat kolom-kolom lainnya.",
        "properties": {
          "outcome": {
            "type": "string",
            "enum": [
              "accepted",
              "edited",
              "overridden",
              "decided_elsewhere",
              "automated"
            ],
            "description": "`accepted` atau `edited` menerima rekomendasi (`edited` dengan narasi yang ditulis ulang), `overridden` mengambil tindakan lain, `decided_elsewhere` adalah keputusan yang diambil di luar Investigator saat laporan masih terbuka, `automated` adalah keputusan yang diambil sendiri oleh Investigator."
          },
          "action": {
            "type": "string",
            "enum": [
              "approve",
              "decline",
              "escalate",
              "request"
            ]
          },
          "actor_email": {
            "type": "string",
            "nullable": true
          },
          "actor_name": {
            "type": "string",
            "nullable": true
          },
          "override_category": {
            "type": "string",
            "enum": [
              "missing_context",
              "needs_information",
              "policy_differs",
              "evidence_misread",
              "other",
              ""
            ],
            "nullable": true
          },
          "override_reason": {
            "type": "string",
            "nullable": true
          },
          "final_status": {
            "type": "string",
            "description": "Status item setelah keputusan."
          },
          "agreed": {
            "type": "boolean",
            "description": "Apakah keputusan sesuai dengan rekomendasi.",
            "nullable": true
          },
          "decided_at": {
            "type": "string",
            "format": "date-time"
          },
          "billed": {
            "type": "boolean",
            "description": "Peninjauan telah ditagihkan."
          },
          "decided_by": {
            "type": "string",
            "enum": [
              "investigator",
              "member"
            ]
          },
          "original_outcome": {
            "type": "object",
            "description": "Keputusan yang diambil sendiri oleh Investigator, tidak diubah oleh penggantian berikutnya. Null untuk keputusan yang diambil oleh tim.",
            "properties": {
              "action": {
                "type": "string"
              },
              "final_status": {
                "type": "string"
              },
              "decided_at": {
                "type": "string",
                "format": "date-time"
              }
            },
            "nullable": true
          },
          "overrides": {
            "type": "array",
            "description": "Setiap penggantian keputusan yang diambil sendiri oleh Penyelidik, yang terlama terlebih dahulu.",
            "items": {
              "type": "object",
              "properties": {
                "action": {
                  "type": "string"
                },
                "actor_email": {
                  "type": "string",
                  "nullable": true
                },
                "actor_name": {
                  "type": "string",
                  "nullable": true
                },
                "override_category": {
                  "type": "string"
                },
                "override_reason": {
                  "type": "string"
                },
                "previous_status": {
                  "type": "string"
                },
                "final_status": {
                  "type": "string"
                },
                "agreed": {
                  "type": "boolean",
                  "nullable": true
                },
                "overridden_at": {
                  "type": "string",
                  "format": "date-time"
                }
              }
            }
          }
        }
      },
      "InvestigatorBlock": {
        "type": "object",
        "nullable": true,
        "description": "Peninjauan terbaru oleh peninjau untuk item tersebut, atau null jika belum pernah ditinjau. Disertakan oleh keputusan sesi V3 dan sesi bisnis (dan dengan demikian oleh webhook `status.updated`).",
        "properties": {
          "run_id": {
            "type": "string",
            "format": "uuid"
          },
          "status": {
            "type": "string",
            "enum": [
              "running",
              "completed",
              "failed"
            ]
          },
          "stage": {
            "type": "string",
            "enum": [
              "shadow",
              "live"
            ]
          },
          "queue": {
            "type": "string",
            "enum": [
              "kyc",
              "kyb",
              "aml",
              "transactions",
              "cases"
            ]
          },
          "is_open": {
            "type": "boolean"
          },
          "recommendation": {
            "type": "string",
            "enum": [
              "approve",
              "decline",
              "escalate",
              "request"
            ],
            "nullable": true
          },
          "recommendation_detail": {
            "type": "string",
            "nullable": true
          },
          "confidence": {
            "type": "string",
            "enum": [
              "high",
              "moderate",
              "low"
            ],
            "nullable": true
          },
          "summary": {
            "type": "string",
            "nullable": true
          },
          "ready_to_accept": {
            "type": "boolean"
          },
          "prepared_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "automated": {
            "type": "boolean",
            "description": "Investigator memutuskan secara mandiri, meskipun keputusan tersebut kemudian dikesampingkan."
          },
          "decided_by": {
            "type": "string",
            "enum": [
              "investigator",
              "member"
            ],
            "nullable": true
          },
          "decision": {
            "nullable": true,
            "allOf": [
              {
                "$ref": "#/components/schemas/InvestigatorDecision"
              }
            ],
            "type": "object"
          }
        }
      },
      "InvestigatorQueueRow": {
        "type": "object",
        "properties": {
          "run_id": {
            "type": "string",
            "format": "uuid"
          },
          "kind": {
            "type": "string",
            "enum": [
              "session",
              "business_session",
              "transaction",
              "case"
            ]
          },
          "queue": {
            "type": "string",
            "enum": [
              "kyc",
              "kyb",
              "aml",
              "transactions",
              "cases"
            ]
          },
          "stage": {
            "type": "string",
            "enum": [
              "shadow",
              "live"
            ]
          },
          "subject": {
            "type": "object",
            "description": "Item yang sedang ditinjau: `id`, `number`, `status`, `name` dan, tergantung jenisnya, `country`, `workflow`, `vendor_data`, `txn_id`, `amount`, `currency`, `direction`, `title`, atau `priority`.",
            "additionalProperties": true
          },
          "recommendation": {
            "type": "string",
            "enum": [
              "approve",
              "decline",
              "escalate",
              "request"
            ]
          },
          "recommendation_detail": {
            "type": "string"
          },
          "confidence": {
            "type": "string",
            "enum": [
              "high",
              "moderate",
              "low"
            ]
          },
          "summary": {
            "type": "string"
          },
          "sources_count": {
            "type": "integer"
          },
          "ready_to_accept": {
            "type": "boolean"
          },
          "guardrails": {
            "description": "Batasan terkunci yang berlaku untuk item ini, jika ada."
          },
          "waiting_since": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "due_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "prepared_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          }
        }
      },
      "InvestigatorRunDetail": {
        "allOf": [
          {
            "$ref": "#/components/schemas/InvestigatorQueueRow"
          },
          {
            "type": "object",
            "properties": {
              "status": {
                "type": "string"
              },
              "is_open": {
                "type": "boolean"
              },
              "lookups": {
                "type": "integer",
                "description": "Berapa banyak bagian dan catatan tertaut yang dibacanya."
              },
              "duration_ms": {
                "type": "integer",
                "nullable": true
              },
              "agent_version": {
                "type": "string"
              },
              "prepared_before_opened": {
                "type": "boolean",
                "nullable": true
              },
              "report": {
                "type": "object",
                "additionalProperties": true,
                "description": "Laporan: penalaran, poin bukti beserta putusannya (`ok`, `risk`, `look`, `explained`, `context`) dan sumber yang dikutip, putusan kecocokan skrining (`same`, `not_same`, `unclear`), serta langkah lanjutan yang disarankan."
              },
              "trail": {
                "description": "Yang saya periksa: ringkasan, bagian, dan catatan yang dibaca, secara berurutan."
              },
              "decision": {
                "nullable": true,
                "allOf": [
                  {
                    "$ref": "#/components/schemas/InvestigatorDecision"
                  }
                ],
                "type": "object"
              },
              "autonomy": {
                "type": "object",
                "additionalProperties": true,
                "description": "Keputusan yang diambil oleh automasi terhadap laporan (`result`, `reason`, `tier`, `policy_version`, `rule`, `agreement`, `decisions`, `threshold`, `at`). Null jika antrean tidak diotomatiskan.",
                "nullable": true
              }
            }
          }
        ]
      },
      "InvestigatorAcceptRequest": {
        "type": "object",
        "properties": {
          "narrative": {
            "type": "string",
            "maxLength": 4000,
            "description": "Narasi yang ditulis ulang. Mengirimkannya akan mencatat keputusan sebagai telah diedit dan diterima."
          },
          "send_email": {
            "type": "boolean",
            "default": false,
            "description": "Kirim email kepada orang tersebut mengenai keputusannya."
          },
          "email_address": {
            "type": "string",
            "format": "email",
            "description": "Wajib jika `send_email` bernilai true."
          },
          "email_language": {
            "type": "string",
            "default": "en",
            "maxLength": 16
          }
        }
      },
      "InvestigatorOverrideRequest": {
        "type": "object",
        "required": [
          "action",
          "category",
          "reason"
        ],
        "properties": {
          "action": {
            "type": "string",
            "enum": [
              "approve",
              "decline",
              "escalate",
              "request"
            ]
          },
          "category": {
            "type": "string",
            "enum": [
              "missing_context",
              "needs_information",
              "policy_differs",
              "evidence_misread",
              "other"
            ]
          },
          "reason": {
            "type": "string",
            "minLength": 10,
            "maxLength": 500
          },
          "send_email": {
            "type": "boolean",
            "default": false,
            "description": "Kirim email kepada orang tersebut mengenai keputusannya."
          },
          "email_address": {
            "type": "string",
            "format": "email",
            "description": "Wajib jika `send_email` bernilai true."
          },
          "email_language": {
            "type": "string",
            "default": "en",
            "maxLength": 16
          }
        }
      },
      "InvestigatorBatchAcceptRequest": {
        "type": "object",
        "required": [
          "run_ids"
        ],
        "properties": {
          "run_ids": {
            "type": "array",
            "minItems": 1,
            "maxItems": 50,
            "items": {
              "type": "string",
              "format": "uuid"
            }
          }
        }
      },
      "InvestigatorBatchAcceptResponse": {
        "type": "object",
        "properties": {
          "accepted": {
            "type": "integer"
          },
          "skipped": {
            "type": "integer"
          },
          "results": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "run_id": {
                  "type": "string",
                  "format": "uuid"
                },
                "result": {
                  "type": "string",
                  "enum": [
                    "accepted",
                    "skipped"
                  ]
                },
                "reason": {
                  "type": "string",
                  "enum": [
                    "not_found",
                    "forbidden",
                    "already_decided",
                    "not_ready",
                    "guardrail",
                    "invalid"
                  ]
                },
                "detail": {},
                "action": {
                  "type": "string"
                },
                "final_status": {
                  "type": "string"
                }
              }
            }
          }
        }
      },
      "InvestigatorSettings": {
        "type": "object",
        "properties": {
          "stage": {
            "type": "string",
            "enum": [
              "none",
              "shadow",
              "live"
            ]
          },
          "stage_changed_at": {
            "type": "string",
            "format": "date-time",
            "readOnly": true,
            "nullable": true
          },
          "stage_changed_by": {
            "type": "string",
            "readOnly": true
          },
          "monthly_spend_limit": {
            "type": "string",
            "format": "decimal",
            "description": "Batas bulanan dalam mata uang penagihan Anda, 0.01 hingga 1,000,000. Null akan menonaktifkannya.",
            "nullable": true
          },
          "spend_limit": {
            "type": "object",
            "readOnly": true,
            "properties": {
              "enabled": {
                "type": "boolean"
              },
              "limit": {
                "type": "string",
                "format": "decimal",
                "nullable": true
              },
              "spent": {
                "type": "string",
                "format": "decimal"
              },
              "reviews": {
                "type": "integer"
              },
              "reserved": {
                "type": "string",
                "format": "decimal",
                "description": "Harga setiap laporan langsung yang terbuka, ditahan karena menerimanya akan dikenakan biaya."
              },
              "currency": {
                "type": "string"
              },
              "paused": {
                "type": "boolean",
                "description": "Mencapai batas: tidak ada peninjauan baru yang dimulai."
              }
            }
          }
        }
      },
      "TravelRuleUtxoEntry": {
        "type": "object",
        "description": "Satu input atau output dari transaksi UTXO, sebagaimana dicatat oleh rantai blockchain.",
        "required": [
          "address"
        ],
        "properties": {
          "address": {
            "type": "string",
            "maxLength": 128
          },
          "amount": {
            "type": "string",
            "nullable": true,
            "description": "String desimal dalam unit koin itu sendiri (BTC, bukan satoshi). Opsional.",
            "example": "0.0125"
          },
          "txid": {
            "type": "string",
            "maxLength": 128,
            "description": "Opsional. Transaksi yang digunakan oleh input."
          },
          "vout": {
            "type": "integer",
            "nullable": true,
            "minimum": 0,
            "description": "Opsional. Indeks output yang digunakan oleh input."
          }
        }
      },
      "TravelRuleUtxo": {
        "type": "object",
        "description": "Input dan output dari transfer UTXO (BTC, LTC, BCH, DOGE). Hanya diterima pada blockchain tersebut: pada blockchain lain akan menghasilkan `400`. Dari informasi tersebut, Didit menyimpulkan dompet pengirim (yang dideklarasikan, jika tidak ada maka alamat input yang berkontribusi paling banyak) dan output penerima (yang dideklarasikan, jika tidak ada maka satu-satunya output yang tidak mengembalikan kembalian ke alamat input, jika tidak ada maka output yang membayar jumlah transfer). Hasilnya ada di `chain_details` transfer tersebut.",
        "required": [
          "outputs"
        ],
        "properties": {
          "inputs": {
            "type": "array",
            "maxItems": 1000,
            "items": {
              "$ref": "#/components/schemas/TravelRuleUtxoEntry"
            },
            "description": "Opsional. Tanpa input, tidak ada pengirim yang disimpulkan dan tidak ada output kembalian (change) yang dikenali."
          },
          "outputs": {
            "type": "array",
            "minItems": 1,
            "maxItems": 1000,
            "items": {
              "$ref": "#/components/schemas/TravelRuleUtxoEntry"
            }
          }
        }
      },
      "TravelRuleChainSide": {
        "type": "object",
        "description": "Dompet salah satu pihak sebagaimana Didit menyelesaikannya dari data chain.",
        "properties": {
          "address": {
            "type": "string",
            "description": "Dompet. Pada jaringan memo berupa alamat klasik (alamat X XRP dipisahkan menjadi alamat klasik dan tag-nya); pada Lightning berupa ID node penerima pembayaran atau Lightning Address."
          },
          "memo": {
            "type": "string",
            "description": "Destination tag atau memo yang merupakan bagian dari dompet; `\"\"` jika tidak ada."
          },
          "source": {
            "type": "string",
            "enum": [
              "declared",
              "x_address",
              "largest_input",
              "only_non_change_output",
              "amount_match",
              "invoice_payee",
              "updated"
            ],
            "description": "Asal dompet: `declared` (permintaan Anda), `x_address` (dipisahkan dari X-address XRP), `largest_input` (alamat input UTXO yang berkontribusi paling banyak), `only_non_change_output` (satu-satunya output UTXO yang bukan kembalian), `amount_match` (satu output UTXO yang membayar jumlah transfer), `invoice_payee` (penerima pembayaran yang disebutkan dalam permintaan pembayaran Lightning), `updated` (ditetapkan kemudian dengan `action: update_originator_wallet`)."
          }
        }
      },
      "TravelRuleChainDetails": {
        "type": "object",
        "description": "Bagaimana rantai transfer menamai kedua dompetnya, ketika melibatkan lebih dari satu alamat yang membayar satu sama lain. Kosong (`{}`) untuk transfer rantai akun (EVM, Solana, Tron), di mana kedua alamat tersebut adalah dompetnya. Pencocokan, perutean, dan buku alamat membaca dompet dari sini terlebih dahulu.",
        "properties": {
          "chain": {
            "type": "string",
            "description": "Blockchain kanonis, misalnya `BTC`, `XRP`, atau `LIGHTNING` untuk transfer Lightning."
          },
          "shape": {
            "type": "string",
            "enum": [
              "utxo",
              "memo",
              "lightning"
            ]
          },
          "originator": {
            "$ref": "#/components/schemas/TravelRuleChainSide"
          },
          "beneficiary": {
            "$ref": "#/components/schemas/TravelRuleChainSide"
          },
          "utxo": {
            "type": "object",
            "description": "Pada transfer UTXO: input dan output sebagaimana disimpan (jumlah dalam bentuk string desimal) dan output mana yang dibaca Didit sebagai apa.",
            "properties": {
              "inputs": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/TravelRuleUtxoEntry"
                }
              },
              "outputs": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/TravelRuleUtxoEntry"
                }
              },
              "change_output_indexes": {
                "type": "array",
                "items": {
                  "type": "integer"
                },
                "description": "Output yang membayar kembali alamat input."
              },
              "beneficiary_output_index": {
                "type": "integer",
                "nullable": true,
                "description": "Output yang membayar penerima; null jika tidak ada yang dapat dibedakan."
              }
            }
          },
          "lightning": {
            "type": "object",
            "description": "Pada transfer Lightning: apa yang tertera pada permintaan pembayaran. Selalu berupa `kind` (`bolt11`, `bolt12_offer`, `bolt12_invoice`, `bolt12_invoice_request`, `lnurl`, `lightning_address`, `node_id`, atau `unknown`); faktur BOLT11 menambahkan `network`, `payee_node_id`, `payment_hash`, `amount_msat`, `created_at`, dan `expires_at`; string BOLT12 menambahkan `blinded_paths` dan `payee_node_id`; LNURL atau Lightning Address menambahkan `domain`-nya. Tidak ada yang di-resolve melalui jaringan: permintaan hanya didekode.",
            "additionalProperties": true
          },
          "warnings": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "declared_originator_not_an_input",
                "declared_beneficiary_not_an_output",
                "beneficiary_output_ambiguous",
                "beneficiary_output_amount_differs"
              ]
            },
            "description": "Inkonsistensi UTXO yang perlu diperiksa: pengirim yang dideklarasikan bukan merupakan input, penerima yang dideklarasikan bukan merupakan output, tidak ada satu pun output penerima yang dapat dibedakan, atau output penerima membayar jumlah yang berbeda dari yang tertera pada transaksi."
          },
          "not_applicable_reason": {
            "type": "string",
            "enum": [
              "LIGHTNING_NO_PAYEE_IDENTIFIER",
              "LIGHTNING_BOLT12_BLINDED_PAYEE",
              "LIGHTNING_LNURL_NAMES_NO_PAYEE"
            ],
            "description": "Pada transfer Lightning keluar yang permintaan pembayarannya tidak menyebutkan penerima: alasan transfer berstatus `NOT_APPLICABLE`. `LIGHTNING_NO_PAYEE_IDENTIFIER` (permintaan tidak menyebutkan node penerima, atau tidak dapat didekode), `LIGHTNING_BOLT12_BLINDED_PAYEE` (penawaran menyembunyikan penerimanya di balik blinded path), `LIGHTNING_LNURL_NAMES_NO_PAYEE` (LNURL menyebutkan nama layanan, bukan penerima). Kode yang sama membuka entri `timeline` terakhir dari transfer."
          }
        }
      },
      "WalletAddressImportRow": {
        "type": "object",
        "description": "Satu dompet untuk diimpor: berdasarkan `address`, `address_hash`, atau keduanya. Bentuk camelCase dari kolom-kolom ini juga diterima, begitu pula `walletAddress`, `walletAddressHash`, `destinationTag`, dan `externalUserId`.",
        "properties": {
          "address": {
            "type": "string",
            "maxLength": 128,
            "description": "Alamat dompet. Alias: `walletAddress`."
          },
          "address_hash": {
            "type": "string",
            "description": "SHA-256 dari alamat berhuruf kecil, sebagai 64 karakter heksadesimal atau 44 karakter base64. Kirimkan parameter ini saja untuk mendaftarkan dompet tanpa mengungkapkan alamatnya; jika dikirim bersama `address`, nilainya harus merupakan hash dari alamat tersebut. Alias: `walletAddressHash`."
          },
          "chain": {
            "type": "string",
            "maxLength": 32
          },
          "memo": {
            "type": "string",
            "maxLength": 256,
            "description": "Tag atau memo tujuan. XRP: tag tujuan, bilangan bulat dari 0 hingga 4294967295 (angka JSON diterima). XLM: memo teks hingga 28 bita, ID 64-bit, atau hash 32-bita dalam heksadesimal. EOS: hingga 256 bita. ATOM: hingga 256 karakter. HBAR: hingga 100 bita. Dompet Bitcoin, EVM, Solana, Tron, Litecoin, Bitcoin Cash, Dogecoin, dan Lightning tidak memerlukan memo: menyertakan memo menghasilkan `400`."
          },
          "holder_name": {
            "type": "string",
            "maxLength": 255
          },
          "holder_vendor_data": {
            "type": "string",
            "maxLength": 255,
            "description": "Pengenal internal Anda untuk pemegang. Alias: `externalUserId`."
          },
          "entity_type": {
            "type": "string",
            "enum": [
              "individual",
              "company"
            ],
            "default": "individual"
          },
          "label": {
            "type": "string",
            "maxLength": 255
          },
          "owner_type": {
            "type": "string",
            "enum": [
              "customer",
              "internal",
              "vasp"
            ],
            "default": "customer"
          },
          "travel_address": {
            "type": "string",
            "maxLength": 512
          },
          "self_declared": {
            "type": "boolean",
            "default": false,
            "description": "Buat entri yang sudah diverifikasi melalui deklarasi mandiri, jika pengaturan Anda mengizinkannya."
          }
        }
      },
      "WalletAddressImportReport": {
        "type": "object",
        "description": "Hal yang terjadi pada setiap baris impor, sesuai urutan pengiriman.",
        "properties": {
          "total": {
            "type": "integer"
          },
          "created": {
            "type": "integer"
          },
          "existing": {
            "type": "integer"
          },
          "duplicate": {
            "type": "integer"
          },
          "failed": {
            "type": "integer"
          },
          "rows": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "row": {
                  "type": "integer",
                  "description": "Nomor baris, mulai dari 1."
                },
                "status": {
                  "type": "string",
                  "enum": [
                    "created",
                    "existing",
                    "duplicate",
                    "failed"
                  ],
                  "description": "`created`: ditambahkan ke buku. `existing`: dompet sudah ada di dalam buku dan dibiarkan tanpa perubahan. `duplicate`: mengulang baris sebelumnya dari impor ini. `failed`: lihat `errors`."
                },
                "entry_id": {
                  "type": "string",
                  "format": "uuid",
                  "nullable": true,
                  "description": "Entri buku alamat yang dibuat atau ditemukan oleh baris tersebut."
                },
                "errors": {
                  "type": "object",
                  "description": "Error kolom dari baris `failed`; jika tidak, kosong."
                },
                "duplicate_of_row": {
                  "type": "integer",
                  "nullable": true,
                  "description": "Pada baris `duplicate`, baris yang diulanginya."
                }
              }
            }
          }
        }
      },
      "TravelRuleCounterpartyContact": {
        "type": "object",
        "description": "Alamat kepatuhan yang dikirimi pesan oleh rel EMAIL untuk satu entri direktori.",
        "properties": {
          "uuid": {
            "type": "string",
            "format": "uuid"
          },
          "counterparty": {
            "type": "string",
            "format": "uuid",
            "description": "Nilai `id` entri direktori, sebagaimana ditampilkan oleh GET /v3/travel-rule/vasps/."
          },
          "counterparty_name": {
            "type": "string"
          },
          "email": {
            "type": "string",
            "format": "email"
          },
          "name": {
            "type": "string",
            "description": "Label opsional, misalnya nama tim."
          },
          "source": {
            "type": "string",
            "enum": [
              "staff",
              "application",
              "learned"
            ],
            "description": "staff: dikurasi oleh Didit. learned: alamat di salah satu domain milik VASP yang menjawab permintaan melalui tautan responsnya. application: ditambahkan oleh aplikasi Anda."
          },
          "scope": {
            "type": "string",
            "enum": [
              "platform",
              "application"
            ],
            "description": "platform: dikurasi oleh Didit atau dipelajari dari jawaban terverifikasi, digunakan untuk setiap pelanggan Didit, hanya dapat dibaca oleh Anda. application: privat untuk aplikasi Anda."
          },
          "created_by": {
            "type": "string",
            "description": "Kosong untuk kontak platform dan untuk kontak yang ditambahkan oleh kunci API."
          },
          "verified_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Kapan alamat ini terakhir kali menjawab permintaan melalui tautan responsnya."
          },
          "is_invalid": {
            "type": "boolean",
            "description": "true setelah alamat mengalami bounce atau mengajukan komplain; jalur EMAIL akan melewatinya."
          },
          "invalid_reason": {
            "type": "string",
            "enum": [
              "",
              "hard_bounce",
              "soft_bounce",
              "spam_complaint",
              "suppressed"
            ]
          },
          "invalid_detail": {
            "type": "string",
            "description": "Alasan dari server email penerima, jika ada."
          },
          "invalid_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "TravelRuleCounterpartyContactCreate": {
        "type": "object",
        "required": [
          "counterparty",
          "email"
        ],
        "properties": {
          "counterparty": {
            "type": "string",
            "format": "uuid",
            "description": "Nilai `id` entri direktori."
          },
          "email": {
            "type": "string",
            "format": "email",
            "maxLength": 254
          },
          "name": {
            "type": "string",
            "description": "Label opsional.",
            "maxLength": 255
          }
        }
      },
      "TravelRuleNameMatch": {
        "type": "object",
        "nullable": true,
        "description": "Perbandingan nama yang menentukan transfer, atau null hingga perbandingan dijalankan. Saat para pihak disamarkan, dan pada salinan pertukaran INTERNAL milik pelanggan lain, `transfer_name`, `compared_name`, `matched_names`, dan `mismatched_names` disembunyikan. `score` dan `matched` bisa tidak sejalan: `matched` mengikuti tingkat ketatnya, sedangkan `score` adalah kesamaan dari kedua nama lengkap tersebut.",
        "properties": {
          "score": {
            "type": "integer",
            "minimum": 0,
            "maximum": 100,
            "description": "Kemiripan antara kedua nama lengkap, 0 hingga 100. Bernilai 0 jika salah satu nama kosong."
          },
          "matched": {
            "type": "boolean",
            "description": "Apakah nama-nama tersebut memenuhi `strictness`. Hasil transfer mengikuti `data_match`, yang membandingkan setiap kolom, sehingga transfer dapat berstatus COUNTERPARTY_MISMATCHED_DATA meskipun ini bernilai true."
          },
          "method": {
            "type": "string",
            "enum": [
              "none",
              "exact_token",
              "token_subset",
              "token_containment",
              "sequence_ratio"
            ],
            "description": "Cara `matched` ditentukan: none (`NONE`), exact_token (`STRICT`), token_subset (`DEFAULT`), token_containment (`CONTAINS`), atau sequence_ratio (`FUZZY`)."
          },
          "strictness": {
            "type": "string",
            "enum": [
              "NONE",
              "STRICT",
              "CONTAINS",
              "DEFAULT",
              "FUZZY"
            ]
          },
          "compared_with": {
            "type": "string",
            "enum": [
              "wallet_holder",
              "counterparty_vasp"
            ],
            "description": "wallet_holder: pemegang yang tercatat untuk dompet tersebut. counterparty_vasp: nama yang diberikan pihak lawan di halaman respons email, atau jawaban Didit Test VASP di sandbox."
          },
          "transfer_name": {
            "type": "string",
            "description": "Nama pada transfer."
          },
          "compared_name": {
            "type": "string",
            "description": "Nama yang dibandingkan dengannya."
          },
          "matched_names": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Kata-kata dari `transfer_name` yang ditemukan di `compared_name`."
          },
          "mismatched_names": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Kata-kata dari `transfer_name` yang tidak ditemukan di `compared_name`, lalu kata-kata dari `compared_name` yang tidak ditemukan di `transfer_name`."
          }
        }
      },
      "TravelRuleTransferRow": {
        "type": "object",
        "description": "Satu transfer Travel Rule seperti yang ditampilkan dalam daftar transfer: hanya nama VASP, dompet, dan memo, tanpa data pribadi pengirim atau penerima.",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "id transfer."
          },
          "transaction_id": {
            "type": "string",
            "format": "uuid",
            "description": "Transaksi Didit yang terkait dengan transfer tersebut."
          },
          "txn_id": {
            "type": "string",
            "nullable": true,
            "description": "ID Anda sendiri untuk transaksi tersebut. Transfer yang dicatat Didit untuk Anda, seperti transfer masuk Didit Test VASP, membawa ID yang dibuat secara otomatis."
          },
          "txn_date": {
            "type": "string",
            "format": "date-time"
          },
          "kind": {
            "type": "string",
            "enum": [
              "withdrawal",
              "deposit",
              "message"
            ],
            "description": "withdrawal: keluar. message: transfer masuk yang dibuat oleh jalur berdasarkan pesan pihak lawan (pertanyaan TRP, bagian masuk INTERNAL, atau pesan GTR, VerifyVASP, atau Sygna Bridge). deposit: transfer masuk lainnya."
          },
          "direction": {
            "type": "string",
            "enum": [
              "INBOUND",
              "OUTBOUND"
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "AWAITING_COUNTERPARTY",
              "ON_HOLD",
              "COMPLETED",
              "FINISHED",
              "CANCELLED",
              "EXPIRED",
              "COUNTERPARTY_MISMATCHED_DATA",
              "COUNTERPARTY_VASP_NOT_FOUND",
              "COUNTERPARTY_VASP_NOT_REACHABLE",
              "UNCONFIRMED_OWNERSHIP",
              "COUNTERPARTY_VASP_GENERAL_DECLINE",
              "NOT_ENOUGH_COUNTERPARTY_DATA",
              "NOT_APPLICABLE"
            ]
          },
          "reason": {
            "type": "string",
            "description": "Alasan transfer `COUNTERPARTY_VASP_NOT_FOUND` atau `COUNTERPARTY_VASP_NOT_REACHABLE` tertahan, nilai yang sama dengan `reason` transfer itu sendiri, sehingga daftar tersebut membedakan email kepatuhan yang dikembalikan dari pihak lawan tanpa rute tanpa harus membuka setiap transfer. `\"\"` untuk status lainnya. Lihat [Mengapa transfer tertahan](/id/transaction-monitoring/travel-rule#mengapa-transfer-macet)."
          },
          "rail": {
            "type": "string",
            "nullable": true,
            "enum": [
              "INTERNAL",
              "TRP",
              "GTR",
              "TRUST",
              "VERIFYVASP",
              "SYGNA",
              "EMAIL",
              "TEST_VASP",
              null
            ]
          },
          "asset": {
            "type": "string",
            "description": "Mata uang transaksi."
          },
          "amount": {
            "type": "string",
            "description": "Jumlah sebagai desimal biasa, misalnya \"1.25\"."
          },
          "originator_vasp": {
            "type": "string",
            "description": "Keluar: nama resmi VASP Anda. Masuk: nama pihak lawan, dari entri direktorinya, anggota jaringan Didit, pengirim TRP, Didit Test VASP, atau nama yang dinyatakan transfer. Kosong jika tidak ada yang diketahui."
          },
          "beneficiary_vasp": {
            "type": "string",
            "description": "Keluar: nama pihak lawan, ditentukan dengan cara yang sama. Masuk: nama resmi VASP Anda."
          },
          "originator_wallet": {
            "type": "string"
          },
          "beneficiary_wallet": {
            "type": "string"
          },
          "originator_memo": {
            "type": "string",
            "description": "Memo atau tag tujuan, kosong pada rantai yang tidak memilikinya."
          },
          "beneficiary_memo": {
            "type": "string"
          },
          "originator_wallet_type": {
            "type": "string",
            "enum": [
              "vasp",
              "self_hosted",
              "own"
            ],
            "description": "vasp, self_hosted (dinyatakan unhosted) atau own (dompet yang dicatat oleh buku alamat Anda sebagai milik Anda). Sisi Anda sendiri selalu vasp."
          },
          "beneficiary_wallet_type": {
            "type": "string",
            "enum": [
              "vasp",
              "self_hosted",
              "own"
            ]
          },
          "matched_transaction_id": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "Sisi lain dari setoran yang Anda cocokkan secara manual dengan transfer yang diumumkan."
          },
          "deadline_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Kapan transfer kedaluwarsa jika masih menunggu pihak lawannya. Ditetapkan pada setiap transfer yang Anda buat dengan `POST /v3/transactions/` yang memerlukan pertukaran, keluar atau masuk. Bernilai null di bawah ambang batas, pada pembayaran Lightning yang tidak berlaku Travel Rule, dan pada transfer masuk yang dibuat Didit saat pihak lawan menghubungi Anda (permintaan TRP masuk, pesan jaringan, atau bagian masuk INTERNAL)."
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "BankAccountCheckHolder": {
        "description": "Nama yang digunakan untuk memeriksa akun. Kirim tepat salah satu dari `full_name` dan `business_name`.",
        "oneOf": [
          {
            "$ref": "#/components/schemas/BankAccountCheckPersonHolder"
          },
          {
            "$ref": "#/components/schemas/BankAccountCheckBusinessHolder"
          }
        ]
      },
      "BankAccountCheckRequest": {
        "type": "object",
        "required": [
          "country",
          "account",
          "holder"
        ],
        "properties": {
          "country": {
            "type": "string",
            "minLength": 3,
            "maxLength": 3,
            "description": "Negara akun, sebagai kode ISO 3166-1 alpha-3, misalnya `NGA`. Huruf kecil diterima.",
            "example": "NGA"
          },
          "account": {
            "type": "object",
            "description": "Akun sesuai format penulisan di negaranya: sebuah `iban`, atau sebuah `account_number` dengan kode bank atau cabang yang dibutuhkan negara tersebut (`sort_code`, `routing_number`, `transit_institution`, `bsb`, `ifsc`, `bank_code`, atau `bic`). Meksiko menerima `clabe` dan Argentina menerima `cbu_cvu`, yang sudah mencakup nama bank. Akun bisnis menambahkan `registration_id` jika negara tersebut memintanya. Spasi, tanda hubung, dan titik diabaikan. Kunci yang tidak digunakan oleh pemeriksaan negara tersebut akan diabaikan; kunci yang dibutuhkan tetapi tidak diberikan akan menghasilkan `400` yang menyebutkan kuncinya.",
            "properties": {
              "iban": {
                "type": "string",
                "maxLength": 64,
                "description": "IBAN, di negara yang menggunakan IBAN. IBAN harus berasal dari `country`."
              },
              "account_number": {
                "type": "string",
                "maxLength": 64,
                "description": "Nomor akun, di negara yang menulis akun dengan kode bank atau cabang terpisah."
              },
              "sort_code": {
                "type": "string",
                "maxLength": 64,
                "description": "Inggris Raya: sort code 6 digit."
              },
              "routing_number": {
                "type": "string",
                "maxLength": 64,
                "description": "Amerika Serikat: nomor perutean ABA 9 digit."
              },
              "transit_institution": {
                "type": "string",
                "maxLength": 64,
                "description": "Kanada: 8 digit nomor transit dan institusi."
              },
              "bsb": {
                "type": "string",
                "maxLength": 64,
                "description": "Australia: 6 digit BSB."
              },
              "ifsc": {
                "type": "string",
                "maxLength": 64,
                "description": "India: 11 karakter IFSC."
              },
              "bank_code": {
                "type": "string",
                "maxLength": 64,
                "description": "Kode bank, jika negara memerlukannya, misalnya di Nigeria."
              },
              "bic": {
                "type": "string",
                "maxLength": 64,
                "description": "BIC bank, jika pemeriksaan di negara tersebut memerlukannya."
              },
              "clabe": {
                "type": "string",
                "maxLength": 64,
                "description": "Meksiko: 18 digit CLABE. Nomor ini sudah mencantumkan nama bank."
              },
              "cbu_cvu": {
                "type": "string",
                "maxLength": 64,
                "description": "Argentina: 22 digit CBU atau CVU. Ini sudah mencakup nama bank."
              },
              "registration_id": {
                "type": "string",
                "maxLength": 64,
                "description": "Nomor registrasi akun bisnis, jika negara memintanya."
              }
            },
            "additionalProperties": {
              "type": "string",
              "maxLength": 64
            },
            "example": {
              "bank_code": "000014",
              "account_number": "0123450001"
            }
          },
          "holder": {
            "$ref": "#/components/schemas/BankAccountCheckHolder"
          },
          "vendor_data": {
            "type": "string",
            "nullable": true,
            "description": "Referensi Anda sendiri untuk pemeriksaan ini, dikembalikan tanpa perubahan.",
            "example": "payout_20481"
          },
          "consent": {
            "type": "boolean",
            "default": false,
            "description": "Atur ke `true` jika pemegang akun telah memberikan persetujuan secara eksplisit untuk pemeriksaan ini. Diperlukan di negara-negara yang pemeriksaan akunnya membutuhkan persetujuan tersebut: tanpanya, pemeriksaan ditolak dengan `400` yang memiliki `field` bernilai `consent` dan `reason` bernilai `required`, serta tidak ada tagihan yang dikenakan. Di tempat lain, ini bersifat opsional, dan Didit mencatatnya bersama biaya pemeriksaan saat Anda mengirimkannya.",
            "example": true
          }
        }
      },
      "BankAccountCheckResponse": {
        "type": "object",
        "required": [
          "request_id",
          "result",
          "holder_name",
          "account",
          "vendor_data",
          "created_at"
        ],
        "properties": {
          "request_id": {
            "type": "string",
            "format": "uuid",
            "description": "ID pemeriksaan ini."
          },
          "result": {
            "type": "string",
            "enum": [
              "match",
              "close_match",
              "no_match",
              "cannot_verify"
            ],
            "description": "`match`: bank menyimpan rekening dengan nama yang Anda kirimkan. `close_match`: dengan nama yang mirip, misalnya nama tengah yang hilang atau salah ketik. `no_match`: dengan nama lain, atau rekening tersebut tidak ada. `cannot_verify`: bank menjawab tanpa membandingkan nama, misalnya untuk rekening yang diblokir atau ditutup."
          },
          "holder_name": {
            "type": "string",
            "nullable": true,
            "description": "Hanya pada `close_match`, dan hanya saat bank mengembalikannya: nama pada akun, sebagaimana yang tercatat di bank. Jika tidak, `null`."
          },
          "account": {
            "type": "string",
            "description": "Akun, dimasker hingga 4 karakter terakhirnya."
          },
          "vendor_data": {
            "type": "string",
            "nullable": true,
            "description": "Referensi Anda sendiri, persis seperti yang Anda kirimkan."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "Waktu ketika pemeriksaan dijalankan, dalam UTC."
          }
        }
      },
      "BankAccountCheckError": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "detail": {
            "type": "string",
            "description": "Apa yang salah, dalam bahasa Inggris."
          },
          "code": {
            "type": "string",
            "description": "Kode stabil untuk percabangan logika. Tidak ada pada `401` dan `403`."
          },
          "field": {
            "type": "string",
            "description": "Hanya `400`: kolom body yang perlu diperbaiki, sebagai jalur bertitik, misalnya `account.sort_code`."
          },
          "reason": {
            "type": "string",
            "enum": [
              "required",
              "length",
              "format",
              "checksum",
              "country_mismatch",
              "rejected"
            ],
            "description": "Hanya `400`: alasan kolom ditolak. `required`, `length`, `format`, `checksum`, dan `country_mismatch` (IBAN dari negara lain) adalah pemeriksaan Didit sendiri; `rejected` berarti bank menolak akun tersebut seperti yang dikirim."
          }
        }
      },
      "BankVerificationResult": {
        "type": "object",
        "description": "Hasil satu langkah Verifikasi Bank, untuk Verifikasi Pengguna dan Bisnis. `method` menunjukkan cara akun diverifikasi, dan `none` menunjukkan bahwa orang tersebut melanjutkan tanpa bank sebelum ada upaya yang dievaluasi. `continued_without_bank` menunjukkan orang tersebut melanjutkan tanpa bank, juga setelah upaya yang dievaluasi. Lihat [Metode verifikasi bank](/id/core-technology/bank-verification/verification-methods) dan [Saat orang tersebut tidak dapat memverifikasi banknya](/id/core-technology/bank-verification/fallbacks).",
        "properties": {
          "schema_version": {
            "type": "integer",
            "description": "Versi bentuk hasil ini. `1` saat ini."
          },
          "bank_verification_id": {
            "type": "string",
            "format": "uuid",
            "description": "ID hasil ini."
          },
          "node_id": {
            "type": "string",
            "description": "Node alur kerja tempat hasil ini berada."
          },
          "status": {
            "type": "string",
            "enum": [
              "Not Finished",
              "Approved",
              "Declined",
              "In Review",
              "Expired"
            ],
            "description": "Keputusan langkah, setelah tindakan dan aturan statusnya."
          },
          "original_status": {
            "type": "string",
            "nullable": true,
            "description": "Keputusan awal yang dicapai langkah tersebut, sebelum adanya perubahan di kemudian hari seperti peninjauan manual."
          },
          "method": {
            "type": "string",
            "nullable": true,
            "enum": [
              "open_banking",
              "account_lookup",
              "microdeposits",
              "statement",
              "none"
            ],
            "description": "Bagaimana akun diverifikasi: `open_banking` (masuk ke bank: orang tersebut masuk ke bank mereka), `account_lookup` (pemeriksaan akun: orang tersebut mengetikkan detail akun dan bank mengonfirmasi namanya), `microdeposits` atau `statement` (unggahan rekening koran). `none` ketika orang tersebut melanjutkan tanpa bank sebelum ada upaya yang dievaluasi, sehingga tidak ada akun yang diverifikasi. Setelah upaya dievaluasi, nilainya tetap menjadi metode dari upaya tersebut. `null` hingga akun dievaluasi, dan saat alur kerja mempersempit data yang dikembalikannya. Aturan alur kerja membaca nilai yang sama sebagai `bank.method`."
          },
          "provider": {
            "type": "string",
            "nullable": true,
            "description": "Kunci dari rute yang menjalankan koneksi. Baca `method`, bukan kunci ini, untuk mengetahui cara akun diverifikasi."
          },
          "credential_source": {
            "type": "string",
            "nullable": true,
            "enum": [
              "native",
              "byok"
            ],
            "description": "`native`: rute milik Didit sendiri, ditagihkan ke saldo Didit Anda. `byok`: penyedia marketplace yang Anda hubungkan dengan kredensial Anda sendiri."
          },
          "route": {
            "type": "object",
            "nullable": true,
            "description": "Rute yang dipilih sebelum persetujuan. Rute ini tidak pernah berubah setelahnya.",
            "properties": {
              "provider_key": {
                "type": "string",
                "nullable": true,
                "description": "Kunci rute."
              },
              "credential_source": {
                "type": "string",
                "enum": [
                  "native",
                  "byok"
                ]
              },
              "is_fallback": {
                "type": "boolean",
                "description": "Menentukan apakah rute Didit sendiri menggantikan penyedia marketplace yang tidak dapat terhubung."
              },
              "provider_connection_id": {
                "type": "string",
                "nullable": true,
                "description": "Koneksi marketplace yang digunakan, untuk `byok`."
              },
              "requested_scopes": {
                "type": "array",
                "items": {
                  "type": "string"
                },
                "description": "Data yang diminta koneksi, misalnya `ownership` atau `balances`."
              }
            }
          },
          "connection": {
            "type": "object",
            "nullable": true,
            "description": "Koneksi dari upaya terbaru. `null` sebelum upaya pertama.",
            "properties": {
              "status": {
                "type": "string",
                "enum": [
                  "pending",
                  "connected",
                  "cancelled",
                  "timeout",
                  "failed",
                  "unsupported",
                  "revoked",
                  "expired"
                ]
              },
              "institution_id": {
                "type": "string",
                "nullable": true,
                "description": "ID bank. `null` untuk pemeriksaan rekening, ketika tidak ada bank yang dipilih."
              },
              "institution_name": {
                "type": "string",
                "nullable": true,
                "description": "Nama bank. `null` untuk pemeriksaan rekening."
              },
              "institution_country": {
                "type": "string",
                "nullable": true,
                "description": "Negara akun, ISO 3166-1 alpha-3."
              },
              "oauth": {
                "type": "boolean",
                "nullable": true,
                "description": "Apakah proses masuk bank dijalankan melalui OAuth atau app-to-app. `null` untuk pemeriksaan akun."
              },
              "connected_at": {
                "type": "string",
                "format": "date-time",
                "nullable": true,
                "description": "Waktu ketika koneksi berhasil."
              },
              "consent_expires_at": {
                "type": "string",
                "format": "date-time",
                "nullable": true,
                "description": "Waktu ketika persetujuan bank berakhir, untuk login ke bank."
              },
              "last_refreshed_at": {
                "type": "string",
                "format": "date-time",
                "nullable": true,
                "description": "Waktu ketika data keuangan terakhir dibaca kembali."
              },
              "attempts": {
                "type": "integer",
                "description": "Jumlah percobaan yang dilakukan orang tersebut pada langkah ini, semua metode digabungkan."
              },
              "reason_code": {
                "type": "string",
                "nullable": true,
                "description": "Alasan mengapa koneksi bukan `connected` saja, misalnya `USER_CANCELLED`, `INSTITUTION_DOWN`, `ACCOUNT_NOT_FOUND`, `REFERENCE_IDENTITY_MISSING`, atau `VERIFICATION_COMPLETED`."
              }
            }
          },
          "account": {
            "type": "object",
            "nullable": true,
            "description": "Akun yang dievaluasi. `null` hingga akun dievaluasi.",
            "properties": {
              "account_id_masked": {
                "type": "string",
                "nullable": true,
                "description": "Nomor akun, dimasker."
              },
              "iban_masked": {
                "type": "string",
                "nullable": true,
                "description": "IBAN, disamarkan."
              },
              "sort_code": {
                "type": "string",
                "nullable": true,
                "description": "Sort code, di Britania Raya."
              },
              "routing_number_masked": {
                "type": "string",
                "nullable": true,
                "description": "Nomor perutean, disamarkan."
              },
              "type": {
                "type": "string",
                "nullable": true,
                "enum": [
                  "checking",
                  "current",
                  "savings",
                  "business",
                  "other"
                ]
              },
              "subtype": {
                "type": "string",
                "nullable": true,
                "description": "Subtipe rekening milik bank itu sendiri."
              },
              "currency": {
                "type": "string",
                "nullable": true,
                "description": "Mata uang ISO 4217 dari akun."
              },
              "holder_type": {
                "type": "string",
                "nullable": true,
                "enum": [
                  "person",
                  "business",
                  "unknown"
                ]
              },
              "holders_count": {
                "type": "integer",
                "nullable": true
              },
              "is_joint": {
                "type": "boolean",
                "nullable": true
              },
              "is_business": {
                "type": "boolean",
                "nullable": true
              }
            }
          },
          "ownership": {
            "type": "object",
            "nullable": true,
            "description": "Bagaimana pemegang akun dibandingkan dengan identitas terverifikasi. `null` hingga sebuah akun dievaluasi.",
            "properties": {
              "result": {
                "type": "string",
                "enum": [
                  "match",
                  "partial_match",
                  "no_match",
                  "unknown",
                  "not_verifiable"
                ],
                "description": "`partial_match` adalah kecocokan dekat. `not_verifiable`: bank merespons tanpa data pemegang untuk dibandingkan. `unknown`: bukti tidak dapat dibaca, atau tidak ada identitas untuk dibandingkan."
              },
              "reference_identity_source": {
                "type": "string",
                "nullable": true,
                "description": "Langkah yang digunakan untuk membandingkan identitas pemegang dengan identitas langkah tersebut: `kyc`, `database_validation`, `expected_details`, `questionnaire`, `document_ai`, atau `kyb`."
              },
              "name_score": {
                "type": "integer",
                "minimum": 0,
                "maximum": 100,
                "nullable": true,
                "description": "Skor nama pemegang Didit."
              },
              "provider_name_score": {
                "type": "integer",
                "minimum": 0,
                "maximum": 100,
                "nullable": true,
                "description": "Skor nama pemilik dari bank itu sendiri, jika bank mengembalikannya."
              },
              "address_score": {
                "type": "integer",
                "minimum": 0,
                "maximum": 100,
                "nullable": true,
                "description": "Skor alamat pemegang, saat pencocokan alamat dijalankan."
              },
              "email_score": {
                "type": "integer",
                "minimum": 0,
                "maximum": 100,
                "nullable": true,
                "description": "Skor email pemegang, saat pencocokan email dijalankan."
              },
              "phone_score": {
                "type": "integer",
                "minimum": 0,
                "maximum": 100,
                "nullable": true,
                "description": "Skor telepon pemegang, saat pencocokan telepon dijalankan."
              },
              "dob_score": {
                "type": "integer",
                "minimum": 0,
                "maximum": 100,
                "nullable": true,
                "description": "Skor tanggal lahir pemegang, saat bank membagikannya."
              },
              "close_match": {
                "type": "boolean",
                "nullable": true,
                "description": "Apakah nama tersebut masuk ke dalam rentang kecocokan dekat."
              },
              "holder_confirmation": {
                "type": "string",
                "nullable": true,
                "enum": [
                  "pending",
                  "confirmed",
                  "rejected"
                ],
                "description": "Jawaban orang tersebut saat diminta mengonfirmasi nama yang sangat mirip. `null` jika tidak pernah diminta."
              },
              "method": {
                "type": "string",
                "nullable": true,
                "enum": [
                  "exact",
                  "token_set",
                  "nickname",
                  "transliteration",
                  "fuzzy",
                  "provider_only",
                  "microdeposits"
                ],
                "description": "Perbandingan nama mana yang menghasilkan skor tersebut. Ini bukan metode verifikasi: baca `method` tingkat atas untuk mengetahuinya."
              },
              "matched_holder_index": {
                "type": "integer",
                "nullable": true
              },
              "holders": {
                "type": "array",
                "items": {
                  "type": "object"
                },
                "description": "Setiap pemegang rekening yang dicantumkan bank, beserta skornya."
              },
              "owner_identity_available": {
                "type": "boolean",
                "nullable": true
              },
              "evidence_freshness": {
                "type": "string",
                "nullable": true,
                "enum": [
                  "live",
                  "cached",
                  "refreshed"
                ]
              },
              "evaluated_at": {
                "type": "string",
                "format": "date-time",
                "nullable": true,
                "description": "Kapan keputusan dihitung."
              }
            }
          },
          "financial_data": {
            "type": "object",
            "description": "Data keuangan yang dibaca oleh langkah tersebut. Hanya proses masuk bank yang membacanya.",
            "properties": {
              "balances": {
                "type": "object",
                "nullable": true,
                "description": "Dengan cakupan `balances`."
              },
              "transactions": {
                "type": "object",
                "nullable": true,
                "description": "Dengan cakupan `transactions`."
              },
              "income": {
                "type": "object",
                "nullable": true,
                "description": "Dengan cakupan `income`."
              },
              "categorization": {
                "type": "object",
                "nullable": true,
                "description": "Kategorisasi Didit atas transaksi yang dibaca. `null` tanpa transaksi tersebut."
              },
              "not_collected": {
                "type": "array",
                "items": {
                  "type": "string",
                  "enum": [
                    "balances",
                    "income",
                    "transactions"
                  ]
                },
                "description": "Data yang diminta langkah tersebut yang tidak dikumpulkan oleh metode yang memverifikasi akun. Saldo, transaksi, dan pendapatan hanya berasal dari login bank, sehingga akun yang diverifikasi melalui pemeriksaan akun mencantumkannya di sini. Bukan kegagalan. Kosong jika sebaliknya."
              }
            }
          },
          "billing": {
            "type": "object",
            "nullable": true,
            "properties": {
              "route": {
                "type": "string",
                "enum": [
                  "native",
                  "byok"
                ]
              },
              "billed": {
                "type": "boolean"
              },
              "marketplace_fee": {
                "type": "string",
                "nullable": true,
                "description": "Biaya platform marketplace yang dibebankan, untuk `byok`."
              },
              "usage_type": {
                "type": "string",
                "nullable": true,
                "description": "Baris penggunaan tempat biaya dicatat: `bank_verification` untuk masuk bank atau pemeriksaan akun, `bank_statement_upload` untuk pengunggahan rekening koran tanpa upaya bank berbayar sebelumnya, dan `bank_byok_fee` untuk biaya marketplace pada penyedia Anda sendiri. `null` jika tidak ada yang ditagihkan."
              }
            }
          },
          "reference_identity": {
            "type": "object",
            "nullable": true,
            "description": "Identitas yang dibandingkan dengan pemegang, beserta sumbernya."
          },
          "signals": {
            "type": "object",
            "nullable": true,
            "description": "Sinyal akun dibaca dari riwayat transaksi, ketika langkah tersebut membaca riwayat transaksi."
          },
          "connection_abandoned": {
            "type": "boolean",
            "nullable": true,
            "description": "Apakah langkah berakhir tanpa kecocokan setelah orang tersebut meninggalkannya di bank mereka."
          },
          "not_covered": {
            "type": "boolean",
            "nullable": true,
            "description": "Apakah bank atau negara orang tersebut tidak dapat dijangkau pada langkah ini. Juga bernilai `true` ketika orang tersebut melanjutkan tanpa bank karena tidak ada metode yang dapat memverifikasi negara atau bank mereka."
          },
          "continued_without_bank": {
            "type": "boolean",
            "description": "Apakah orang tersebut meninggalkan langkah dengan **Continue without your bank**. `continuation` kemudian menyatakan alasannya. `method` bernilai `none` jika tidak ada upaya yang dievaluasi sebelum mereka melanjutkan. Setelah upaya yang dievaluasi, seperti pemegang rekening yang tidak cocok, `method` tetap menjadi metode upaya tersebut serta putusan dan kode alasannya tetap berlaku. Dikembalikan bahkan ketika alur kerja mempersempit data yang dikembalikannya."
          },
          "continuation": {
            "type": "object",
            "nullable": true,
            "description": "Bagaimana orang tersebut melanjutkan tanpa bank. `null` jika tidak. Saat alur kerja mempersempit data yang dikembalikannya, `reason` tetap dikembalikan dan setiap kunci lainnya bernilai `null`.",
            "properties": {
              "reason": {
                "type": "string",
                "enum": [
                  "no_route",
                  "institution_unsupported",
                  "attempts_exhausted",
                  "person_choice"
                ],
                "description": "Alasan, sebagaimana ditentukan oleh Didit ketika orang tersebut melanjutkan: `no_route` (tidak ada proses masuk bank atau pemeriksaan akun yang melayani negara mereka), `institution_unsupported` (bank yang mereka pilih tidak dapat digunakan pada langkah ini), `attempts_exhausted` (setiap upaya telah habis dan tidak ada yang sedang berlangsung), atau `person_choice` (cara untuk memverifikasi tersedia dan mereka memilih untuk melanjutkan, termasuk ketika bank mereka tidak dapat dihubungi saat ini). `no_route` dan `institution_unsupported` mengikuti `bank_unsupported_action`, `attempts_exhausted` mengikuti `bank_attempts_exhausted_action`, dan `person_choice` mengikuti `bank_skipped_action`, kecuali jika upaya yang dievaluasi telah memutuskan langkah tersebut."
              },
              "country": {
                "type": "string",
                "nullable": true,
                "description": "Negara tempat orang tersebut melakukan verifikasi, ISO 3166-1 alpha-3. Bernilai `null` jika mereka melanjutkan sebelum memilih negara."
              },
              "offered": {
                "type": "array",
                "items": {
                  "type": "string",
                  "enum": [
                    "statement",
                    "microdeposits"
                  ]
                },
                "nullable": true,
                "description": "Cara lain untuk memverifikasi negara tersebut yang ditawarkan kepada orang tersebut saat mereka melanjutkan, sesuai urutan penawarannya: `statement` (unggahan rekening koran), kemudian `microdeposits`. Kosong jika tidak ada yang ditawarkan."
              },
              "institution_id": {
                "type": "string",
                "nullable": true,
                "description": "Untuk `institution_unsupported`, ID bank yang tidak dapat digunakan orang tersebut: bank yang mereka pilih, atau bank tempat percobaan terakhir mereka berakhir. Didit mengambilnya dari daftar bank miliknya sendiri, tidak pernah dari perangkat orang tersebut, sehingga bank yang tidak ada dalam daftar tersebut bernilai `null`. `null` untuk setiap alasan lainnya."
              },
              "institution_name": {
                "type": "string",
                "nullable": true,
                "description": "Untuk `institution_unsupported`, nama bank tersebut, dari daftar yang sama dengan `institution_id`. `null` jika daftar tersebut tidak memiliki bank tersebut, dan untuk setiap alasan lainnya."
              },
              "continued_at": {
                "type": "string",
                "format": "date-time",
                "nullable": true,
                "description": "Waktu pengguna melanjutkan."
              }
            }
          },
          "evidence_purged_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Waktu ketika bukti bank dihapus berdasarkan `bank_evidence_retention_days`. Jika tidak, `null`."
          },
          "warnings": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Kode informasi, misalnya `holder_declared`. Peringatan tidak pernah mengubah status dengan sendirinya."
          },
          "reason_codes": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Alasan mengapa hasil keputusan keluar seperti itu, misalnya `OWNER_NAME_PARTIAL`. Beberapa alasan dapat berlaku. `NOT_COVERED`: orang tersebut melanjutkan tanpa bank karena tidak ada metode yang dapat memverifikasi negara atau bank mereka. `SKIPPED`: orang tersebut memilih untuk melanjutkan tanpa bank saat cara untuk memverifikasi tersedia. Keduanya tidak ditambahkan jika upaya yang dievaluasi telah memutuskan langkah tersebut."
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "BankAccountCheckPersonHolder": {
        "type": "object",
        "description": "Orang yang seharusnya memegang akun tersebut.",
        "required": [
          "full_name"
        ],
        "properties": {
          "full_name": {
            "type": "string",
            "maxLength": 255,
            "description": "Nama lengkap orang yang seharusnya memegang akun tersebut.",
            "example": "Maria Oliveira"
          }
        }
      },
      "BankAccountCheckBusinessHolder": {
        "type": "object",
        "description": "Perusahaan yang seharusnya memegang akun. Memeriksa akun bisnis.",
        "required": [
          "business_name"
        ],
        "properties": {
          "business_name": {
            "type": "string",
            "maxLength": 255,
            "description": "Nama perusahaan yang harus memiliki akun tersebut. Memeriksa akun bisnis."
          }
        }
      },
      "BankVerificationPricing": {
        "type": "object",
        "description": "Daftar harga Verifikasi Bank Publik: unggah laporan mutasi, biaya kunci penyedia Anda sendiri, dan metode masing-masing negara.",
        "required": [
          "currency",
          "statement_upload",
          "own_provider_fee_usd",
          "countries"
        ],
        "properties": {
          "currency": {
            "type": "string",
            "enum": [
              "USD"
            ],
            "description": "Mata uang dari setiap harga dalam respons.",
            "example": "USD"
          },
          "statement_upload": {
            "$ref": "#/components/schemas/BankStatementUploadPricing"
          },
          "own_provider_fee_usd": {
            "type": "string",
            "description": "Biaya untuk setiap pemeriksaan kepemilikan yang dapat ditagih pada rute yang menggunakan kontrak penyedia Anda sendiri alih-alih Didit, yang dikenakan apa pun hasilnya. Koneksi yang dibatalkan, kehabisan waktu, atau ditinggalkan tidak ditagih. String desimal dengan 4 angka di belakang koma, dalam USD.",
            "example": "0.0200"
          },
          "countries": {
            "type": "object",
            "description": "Setiap negara, dengan kunci kode ISO 3166-1 alpha-3.",
            "additionalProperties": {
              "$ref": "#/components/schemas/BankVerificationPricingCountry"
            }
          }
        }
      },
      "BankStatementUploadPricing": {
        "type": "object",
        "description": "Bagaimana harga unggahan rekening koran bank ditentukan.",
        "required": [
          "price_usd",
          "included_after_charged_bank_attempt",
          "standalone_available"
        ],
        "properties": {
          "price_usd": {
            "type": "string",
            "description": "Harga unggahan rekening koran setelah percobaan bank berbayar. String desimal dengan 4 angka desimal, dalam USD.",
            "example": "0.0000"
          },
          "included_after_charged_bank_attempt": {
            "type": "boolean",
            "description": "`true` saat pengunggahan disertakan tanpa biaya tambahan setelah upaya bank berbayar dalam sesi yang sama.",
            "example": true
          },
          "standalone_available": {
            "type": "boolean",
            "description": "`true` jika pengunggahan rekening koran dapat berjalan secara mandiri, tanpa percobaan bank terlebih dahulu. `false` di lingkungan produksi; sesi sandbox dapat mengujinya tanpa penagihan.",
            "example": false
          }
        }
      },
      "BankVerificationPricingCountry": {
        "type": "object",
        "description": "Metode Verifikasi Bank suatu negara beserta harga daftarnya.",
        "required": [
          "name",
          "methods"
        ],
        "properties": {
          "name": {
            "type": "string",
            "description": "Nama negara dalam bahasa Inggris.",
            "example": "United Kingdom"
          },
          "methods": {
            "$ref": "#/components/schemas/BankVerificationPricingMethods"
          }
        }
      },
      "BankVerificationPricingMethods": {
        "type": "object",
        "description": "Dua metode Verifikasi Bank di suatu negara.",
        "required": [
          "open_banking",
          "account_lookup"
        ],
        "properties": {
          "open_banking": {
            "$ref": "#/components/schemas/BankSignInPricing"
          },
          "account_lookup": {
            "$ref": "#/components/schemas/BankAccountCheckPricing"
          }
        }
      },
      "BankSignInPricing": {
        "type": "object",
        "description": "Login ke bank: orang tersebut masuk ke rekening banknya. Diberi harga berdasarkan pasar, sama untuk setiap bank di dalamnya.",
        "required": [
          "available",
          "market",
          "price_usd",
          "add_ons"
        ],
        "properties": {
          "available": {
            "type": "boolean",
            "description": "`true` hanya jika Didit melayani proses masuk bank di negara ini di lingkungan produksi.",
            "example": true
          },
          "market": {
            "type": "string",
            "nullable": true,
            "description": "Pasar yang harganya berlaku. `null` jika tidak tersedia.",
            "example": "UK and EEA"
          },
          "price_usd": {
            "type": "string",
            "nullable": true,
            "description": "Harga standar satu login bank. `null` jika tidak tersedia. String desimal dengan 4 angka desimal, dalam USD.",
            "example": "0.7900"
          },
          "add_ons": {
            "type": "object",
            "description": "Pengaya yang diberi harga di negara ini, masing-masing berupa string desimal dengan 4 angka di belakang koma dalam USD, ditambahkan ke harga login bank. Hanya pengaya yang ditawarkan negara tersebut yang dicantumkan; kosong jika login bank tidak tersedia.",
            "properties": {
              "balance": {
                "type": "string",
                "description": "Pengaya saldo akun.",
                "example": "0.3500"
              },
              "transactions": {
                "type": "string",
                "description": "Add-on transaksi.",
                "example": "1.3000"
              }
            }
          }
        }
      },
      "BankAccountCheckPricing": {
        "type": "object",
        "description": "Pemeriksaan akun: orang tersebut mengetikkan nomor akun mereka dan Didit memeriksanya dengan bank. Harga ditetapkan berdasarkan negara.",
        "required": [
          "available",
          "price_usd"
        ],
        "properties": {
          "available": {
            "type": "boolean",
            "description": "`true` hanya jika Didit melayani pemeriksaan akun di negara ini di lingkungan produksi.",
            "example": true
          },
          "price_usd": {
            "type": "string",
            "nullable": true,
            "description": "Harga terdaftar dari satu pemeriksaan akun yang dijawab bank. `null` jika tidak tersedia. String desimal dengan 4 angka desimal, dalam USD.",
            "example": "0.4000"
          }
        }
      },
      "ImportProvider": {
        "type": "object",
        "properties": {
          "key": {
            "type": "string",
            "enum": [
              "sumsub",
              "jumio",
              "veriff",
              "onfido",
              "persona",
              "metamap",
              "socure",
              "idnow",
              "shufti",
              "idenfy",
              "ondato",
              "trulioo",
              "au10tix",
              "complycube",
              "other"
            ]
          },
          "name": {
            "type": "string"
          },
          "mode": {
            "type": "string",
            "enum": [
              "api_list",
              "api_ids",
              "export_file"
            ],
            "description": "`api_list`: Didit mencantumkan rekaman dengan kunci tersebut. `api_ids`: unggah ID rekaman dari ekspor. `export_file`: unggah ekspor dalam format Didit."
          },
          "record_noun": {
            "type": "string"
          },
          "credential_fields": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "name": {
                  "type": "string"
                },
                "label": {
                  "type": "string"
                },
                "secret": {
                  "type": "boolean"
                }
              }
            }
          },
          "regions": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "required_permissions": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "docs_url": {
            "type": "string",
            "nullable": true
          },
          "status_mapping": {
            "type": "object",
            "additionalProperties": {
              "type": "string",
              "enum": [
                "Approved",
                "Declined",
                "In Review",
                "Expired",
                "Not Finished",
                "Abandoned"
              ]
            }
          }
        }
      },
      "ImportJobSummary": {
        "type": "object",
        "description": "Satu tugas impor dari jenis apa pun, dalam format yang dibaca panel tugas impor di konsol.",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "kind": {
            "type": "string",
            "enum": [
              "sessions",
              "businesses",
              "users",
              "status_rules",
              "transactions"
            ]
          },
          "source": {
            "type": "string",
            "enum": [
              "file",
              "api",
              "provider"
            ]
          },
          "provider": {
            "type": "string",
            "nullable": true
          },
          "provider_name": {
            "type": "string",
            "nullable": true
          },
          "filename": {
            "type": "string",
            "nullable": true
          },
          "state": {
            "type": "string",
            "enum": [
              "ready",
              "queued",
              "running",
              "paused",
              "completed",
              "errors",
              "failed",
              "cancelled"
            ],
            "description": "Status tugas seperti yang ditampilkan konsol; `errors` adalah tugas selesai dengan baris yang ditolak."
          },
          "status": {
            "type": "string"
          },
          "is_dry_run": {
            "type": "boolean"
          },
          "credential_hint": {
            "type": "string",
            "nullable": true
          },
          "resumes_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "last_error": {
            "type": "string",
            "nullable": true
          },
          "started_by": {
            "type": "object",
            "properties": {
              "name": {
                "type": "string",
                "nullable": true
              },
              "email": {
                "type": "string",
                "nullable": true
              }
            }
          },
          "progress": {
            "type": "object",
            "properties": {
              "total": {
                "type": "integer",
                "format": "int64"
              },
              "processed": {
                "type": "integer",
                "format": "int64"
              },
              "imported": {
                "type": "integer",
                "format": "int64"
              },
              "updated": {
                "type": "integer",
                "format": "int64"
              },
              "already_in_didit": {
                "type": "integer",
                "format": "int64"
              },
              "failed": {
                "type": "integer",
                "format": "int64"
              },
              "not_finished": {
                "type": "integer",
                "format": "int64"
              },
              "same_person": {
                "type": "integer",
                "format": "int64"
              }
            }
          },
          "face_templates": {
            "type": "object",
            "nullable": true,
            "properties": {
              "enabled": {
                "type": "boolean"
              },
              "built": {
                "type": "integer",
                "format": "int64"
              },
              "duplicates": {
                "type": "integer",
                "format": "int64"
              },
              "blocklisted": {
                "type": "integer",
                "format": "int64"
              }
            }
          },
          "eta_seconds": {
            "type": "integer",
            "nullable": true
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "started_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "completed_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          }
        }
      },
      "FiledRegulatoryReport": {
        "type": "object",
        "description": "Laporan regulasi yang sudah final mencegah penghapusan yang diminta.",
        "required": [
          "uuid",
          "report_number",
          "report_type",
          "case_uuid"
        ],
        "properties": {
          "uuid": {
            "type": "string",
            "format": "uuid",
            "description": "UUID laporan."
          },
          "report_number": {
            "type": "string",
            "description": "Nomor laporan yang ditampilkan di Console (misalnya, SAR-0001)."
          },
          "report_type": {
            "type": "string",
            "enum": [
              "SAR",
              "STR",
              "CTR",
              "TTR",
              "UTR",
              "IFT",
              "CBR",
              "TFR"
            ],
            "description": "Jenis laporan regulasi."
          },
          "case_uuid": {
            "type": "string",
            "format": "uuid",
            "description": "Kasus tempat laporan ini bernaung."
          }
        }
      },
      "FiledReportTransaction": {
        "type": "object",
        "description": "Transaksi yang tidak dapat dihapus karena tercantum dalam laporan regulasi yang telah difinalisasi.",
        "required": [
          "uuid",
          "transaction_id",
          "reports"
        ],
        "properties": {
          "uuid": {
            "type": "string",
            "format": "uuid",
            "description": "UUID transaksi Didit."
          },
          "transaction_id": {
            "type": "string",
            "description": "Pengidentifikasi transaksi yang diberikan saat transaksi dibuat."
          },
          "reports": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FiledRegulatoryReport"
            },
            "description": "Laporan yang telah difinalisasi dan mencantumkan transaksi ini."
          }
        }
      },
      "InFiledReportError": {
        "type": "object",
        "description": "Penghapusan ditolak karena data yang dipilih berada dalam laporan regulasi yang telah diselesaikan. Tidak ada yang dihapus. Hapus laporan tersebut, lalu ulangi permintaan.",
        "required": [
          "detail",
          "code"
        ],
        "properties": {
          "detail": {
            "type": "string"
          },
          "code": {
            "type": "string",
            "enum": [
              "in_filed_report"
            ],
            "description": "Kode kesalahan stabil untuk penghapusan yang diblokir oleh laporan regulasi yang telah difinalisasi."
          },
          "reports": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FiledRegulatoryReport"
            },
            "description": "Laporan yang memblokir penghapusan orang, perusahaan, kasus, atau sesi."
          },
          "transactions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FiledReportTransaction"
            },
            "description": "Transaksi yang memblokir penghapusan transaksi, masing-masing beserta laporan yang mencantumkannya."
          }
        }
      },
      "SubjectDeletionInProgressError": {
        "type": "object",
        "description": "Permintaan lain masih menghapus individu atau perusahaan ini. Permintaan ini tidak menghapus apa pun dan dapat diulang setelah penghapusan tersebut selesai; pengulangan kemudian akan menghapus apa pun yang masih dipilih.",
        "required": [
          "detail",
          "code"
        ],
        "properties": {
          "detail": {
            "type": "string"
          },
          "code": {
            "type": "string",
            "enum": [
              "subject_deletion_in_progress"
            ],
            "description": "Kode kesalahan stabil untuk individu atau perusahaan yang masih dalam proses penghapusan oleh permintaan lain."
          }
        }
      },
      "TravelRuleNetworkParticipantSummary": {
        "type": "object",
        "nullable": true,
        "description": "Partisipan milik aplikasi ini pada jaringan tersebut, atau null jika tidak ada.",
        "properties": {
          "mode": {
            "type": "string",
            "enum": [
              "platform",
              "own"
            ],
            "description": "platform: dibawa oleh keanggotaan Didit; own: di-onboard di bawah keanggotaan aplikasi itu sendiri."
          },
          "status": {
            "type": "string",
            "enum": [
              "not_requested",
              "questionnaire_pending",
              "submitted_to_network",
              "active",
              "suspended",
              "rejected"
            ],
            "description": "not_requested: tidak pernah diminta, atau jaringan menolak permintaan pertama (lihat last_error); questionnaire_pending: menunggu kuesioner uji tuntas disetujui; submitted_to_network: diserahkan ke proses onboarding jaringan; active: jaringan memberikan kode partisipan tersendiri untuk aplikasi ini; suspended / rejected: Didit menangguhkan atau menolaknya."
          },
          "participant_code": {
            "type": "string",
            "description": "Kode yang diberikan jaringan untuk aplikasi ini (untuk GTR, kode VASP-nya). Pesan keluar memuat kode ini, bukan kode milik Didit."
          },
          "requested_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "activated_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "last_error": {
            "type": "string",
            "description": "Jawaban jaringan saat menolak pendaftaran; kosong jika tidak."
          }
        }
      },
      "TravelRuleNetworkState": {
        "type": "object",
        "description": "Cara pesan Travel Rule pada satu jaringan akan dikirim untuk aplikasi ini, dan alasan pesan tersebut tidak dapat dikirim. Status konfigurasi, bukan pemeriksaan status atau pengiriman secara langsung.",
        "properties": {
          "rail": {
            "type": "string",
            "enum": [
              "GTR",
              "TRUST",
              "VERIFYVASP",
              "SYGNA"
            ]
          },
          "mode": {
            "type": "string",
            "enum": [
              "own",
              "didit",
              "off",
              "unavailable"
            ],
            "description": "own: keanggotaan terhubung milik aplikasi digunakan; didit: keanggotaan Didit membawa aplikasi sebagai partisipan aktifnya sendiri; off: perutean platform dinonaktifkan di disabled_networks tanpa keanggotaan sendiri; unavailable: belum ada yang dapat mengirim di jaringan ini (lihat state dan reason)."
          },
          "state": {
            "type": "string",
            "enum": [
              "own_membership",
              "live_through_didit",
              "off",
              "didit_onboarding",
              "questionnaire_needed",
              "questionnaire_in_review",
              "request_access",
              "request_sent",
              "unavailable",
              "error"
            ],
            "description": "own_membership: keanggotaan terhubung milik Anda yang mengirim; live_through_didit: partisipan Anda sendiri pada keanggotaan Didit yang mengirim; off: Anda menonaktifkan perutean platform; didit_onboarding: keanggotaan Didit sendiri di jaringan ini belum aktif, sehingga belum dapat membawa siapa pun; questionnaire_needed / questionnaire_in_review: kuesioner uji tuntas harus dikirimkan atau sedang ditinjau oleh Didit; request_access: kuesioner disetujui, minta akses ke jaringan; request_sent: partisipan Anda sedang dalam proses onboarding; unavailable: lihat reason; error: lihat reason."
          },
          "reason": {
            "type": "string",
            "enum": [
              "own_membership_connected",
              "platform_network_switched_off",
              "own_membership_only",
              "sandbox_application",
              "didit_membership_not_live",
              "participant_suspended",
              "participant_rejected",
              "questionnaire_not_submitted",
              "questionnaire_submitted",
              "questionnaire_changes_requested",
              "questionnaire_rejected",
              "participant_not_requested",
              "participant_active",
              "participant_key_missing",
              "participant_key_unresolved",
              "provisioning_failed",
              "questionnaire_pending",
              "submitted_to_network"
            ],
            "description": "Detail status yang dapat dibaca mesin. own_membership_only: Didit tidak memiliki aplikasi di jaringan ini (TRUST), hubungkan keanggotaan Anda sendiri; sandbox_application: transfer sandbox tidak pernah mencapai jaringan; provisioning_failed: jaringan menolak registrasi, last_error partisipan menjelaskan alasannya dan permintaan ke jaringan lagi akan mencoba kembali."
          },
          "platform_available": {
            "type": "boolean",
            "description": "Menentukan apakah keanggotaan Didit sendiri di jaringan ini telah dikonfigurasi; bukan pemeriksaan status langsung."
          },
          "connected": {
            "type": "boolean",
            "description": "Menentukan apakah keanggotaan pelanggan yang terhubung ada. Kredensial divalidasi secara lokal; validasi jaringan terjadi pada pertukaran langsung."
          },
          "participant": {
            "$ref": "#/components/schemas/TravelRuleNetworkParticipantSummary"
          },
          "vasps_reachable": {
            "type": "integer",
            "description": "VASP direktori yang dapat dijangkau di jaringan ini."
          },
          "routed_30d": {
            "type": "integer",
            "description": "Transfer milik aplikasi ini yang dilakukan pada jaringan ini dalam 30 hari terakhir."
          }
        }
      },
      "TravelRuleNetworkQuestionnaireAnswers": {
        "type": "object",
        "description": "Kuesioner uji kelayakan jaringan Didit. Penyimpanan bersifat parsial: operasi penyimpanan mempertahankan setiap jawaban yang tidak disebutkan namanya. Pengiriman memerlukan setiap kolom kecuali lei dan data_protection_contact_email, serta ketiga atestasi bernilai true.",
        "properties": {
          "legal_name": {
            "type": "string",
            "maxLength": 255
          },
          "registration_number": {
            "type": "string",
            "maxLength": 255
          },
          "incorporation_country": {
            "type": "string",
            "minLength": 2,
            "maxLength": 2,
            "description": "Kode negara ISO 3166-1 alpha-2."
          },
          "registered_address": {
            "type": "string",
            "maxLength": 1000
          },
          "website": {
            "type": "string",
            "format": "uri",
            "maxLength": 500
          },
          "lei": {
            "type": "string",
            "maxLength": 20,
            "description": "Opsional. LEI ISO 17442 yang valid jika diberikan."
          },
          "licences": {
            "type": "array",
            "minItems": 1,
            "items": {
              "type": "object",
              "required": [
                "regulator",
                "jurisdiction",
                "licence_type",
                "licence_number"
              ],
              "properties": {
                "regulator": {
                  "type": "string",
                  "maxLength": 255
                },
                "jurisdiction": {
                  "type": "string",
                  "minLength": 2,
                  "maxLength": 2,
                  "description": "Kode negara ISO 3166-1 alpha-2."
                },
                "licence_type": {
                  "type": "string",
                  "maxLength": 255
                },
                "licence_number": {
                  "type": "string",
                  "maxLength": 255
                }
              }
            },
            "description": "Setiap lisensi atau registrasi yang dipegang VASP."
          },
          "operating_jurisdictions": {
            "type": "array",
            "minItems": 1,
            "maxItems": 250,
            "items": {
              "type": "string",
              "minLength": 2,
              "maxLength": 2,
              "description": "Kode negara ISO 3166-1 alpha-2."
            }
          },
          "compliance_officer_name": {
            "type": "string",
            "maxLength": 255
          },
          "compliance_officer_email": {
            "type": "string",
            "format": "email"
          },
          "aml_ctf_policy_attested": {
            "type": "boolean",
            "description": "Harus bernilai true untuk mengirimkan."
          },
          "sanctions_screening_attested": {
            "type": "boolean",
            "description": "Harus bernilai true untuk mengirimkan."
          },
          "data_protection_attested": {
            "type": "boolean",
            "description": "Harus bernilai true untuk mengirimkan."
          },
          "data_protection_contact_email": {
            "type": "string",
            "format": "email",
            "description": "Opsional."
          },
          "expected_monthly_transfers": {
            "type": "integer",
            "minimum": 0
          },
          "expected_monthly_volume_usd": {
            "type": "string",
            "format": "decimal",
            "description": "Volume bulanan yang diharapkan dalam USD, hingga 2 tempat desimal. Dikembalikan sebagai string."
          },
          "assets": {
            "type": "array",
            "minItems": 1,
            "maxItems": 200,
            "items": {
              "type": "string",
              "maxLength": 32
            },
            "description": "Ticker aset, disimpan dalam huruf besar, diurutkan, dan dideduplikasi."
          }
        }
      },
      "TravelRuleNetworkQuestionnaire": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "enum": [
              "draft",
              "submitted",
              "changes_requested",
              "approved",
              "rejected"
            ],
            "description": "Jawaban dapat disimpan saat berstatus draft atau changes_requested; perubahan ke status submitted, approved, dan rejected dilakukan oleh Didit."
          },
          "answers": {
            "$ref": "#/components/schemas/TravelRuleNetworkQuestionnaireAnswers"
          },
          "submitted_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "reviewed_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "review_note": {
            "type": "string",
            "description": "Catatan Didit tentang keputusan terakhirnya, misalnya apa yang perlu diubah."
          },
          "history": {
            "type": "array",
            "readOnly": true,
            "description": "Setiap perubahan status, yang terlama terlebih dahulu.",
            "items": {
              "type": "object",
              "properties": {
                "at": {
                  "type": "string",
                  "format": "date-time"
                },
                "from": {
                  "type": "string"
                },
                "to": {
                  "type": "string"
                },
                "note": {
                  "type": "string",
                  "description": "Catatan peninjauan atau jawaban jaringan, jika ada."
                }
              }
            }
          },
          "updated_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          }
        }
      },
      "TravelRuleNetworkParticipant": {
        "type": "object",
        "description": "Partisipan milik aplikasi ini pada satu jaringan.",
        "properties": {
          "network": {
            "type": "string",
            "enum": [
              "gtr",
              "trust",
              "verifyvasp",
              "sygna"
            ]
          },
          "rail": {
            "type": "string",
            "enum": [
              "GTR",
              "TRUST",
              "VERIFYVASP",
              "SYGNA"
            ]
          },
          "mode": {
            "type": "string",
            "enum": [
              "platform",
              "own"
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "not_requested",
              "questionnaire_pending",
              "submitted_to_network",
              "active",
              "suspended",
              "rejected"
            ],
            "description": "not_requested: tidak pernah diminta, atau jaringan menolak permintaan pertama (lihat last_error); questionnaire_pending: menunggu kuesioner uji tuntas disetujui; submitted_to_network: diserahkan ke proses onboarding jaringan; active: jaringan memberikan kode partisipan tersendiri untuk aplikasi ini; suspended / rejected: Didit menangguhkan atau menolaknya."
          },
          "participant_code": {
            "type": "string"
          },
          "requested_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "submitted_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "activated_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "suspended_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "last_error": {
            "type": "string",
            "description": "Jawaban jaringan saat menolak pendaftaran; kosong jika tidak."
          },
          "history": {
            "type": "array",
            "readOnly": true,
            "description": "Setiap perubahan status, yang terlama terlebih dahulu.",
            "items": {
              "type": "object",
              "properties": {
                "at": {
                  "type": "string",
                  "format": "date-time"
                },
                "from": {
                  "type": "string"
                },
                "to": {
                  "type": "string"
                },
                "note": {
                  "type": "string",
                  "description": "Catatan peninjauan atau jawaban jaringan, jika ada."
                }
              }
            }
          }
        }
      },
      "TravelRuleNetworksOverview": {
        "type": "object",
        "properties": {
          "platform_networks_enabled": {
            "type": "boolean",
            "description": "Menentukan apakah akses jaringan melalui keanggotaan Didit terbuka. Saat bernilai false, penyimpanan kuesioner, pengiriman, dan permintaan jaringan menghasilkan respons 403."
          },
          "questionnaire": {
            "$ref": "#/components/schemas/TravelRuleNetworkQuestionnaire"
          },
          "participants": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TravelRuleNetworkParticipant"
            }
          },
          "networks": {
            "type": "object",
            "readOnly": true,
            "description": "Per jaringan, bagaimana aplikasi ini akan mengirim dan mengapa aplikasi ini tidak dapat mengirim. Tidak ada jaringan, termasuk GTR, yang disertakan secara default: jaringan dapat dijangkau melalui keanggotaan terhubung Anda sendiri, atau melalui keanggotaan Didit setelah keanggotaan Didit di jaringan tersebut aktif dan partisipan Anda sendiri di dalamnya aktif. Bukan pemeriksaan status atau pengiriman langsung.",
            "properties": {
              "gtr": {
                "$ref": "#/components/schemas/TravelRuleNetworkState"
              },
              "trust": {
                "$ref": "#/components/schemas/TravelRuleNetworkState"
              },
              "verifyvasp": {
                "$ref": "#/components/schemas/TravelRuleNetworkState"
              },
              "sygna": {
                "$ref": "#/components/schemas/TravelRuleNetworkState"
              }
            }
          }
        }
      },
      "AddressValidationResult": {
        "type": "object",
        "description": "Hasil dari satu Validasi Alamat: apakah alamat tersebut ada, dan bentuk yang telah dinormalisasi. Ini hanya mengonfirmasi alamat; ini tidak pernah menautkan alamat ke seseorang.",
        "required": [
          "status",
          "verification_level",
          "address",
          "formatted_address",
          "latitude",
          "longitude"
        ],
        "properties": {
          "status": {
            "type": "string",
            "enum": [
              "verified",
              "partially_verified",
              "not_verified",
              "unavailable"
            ],
            "description": "`verified`: alamat dikonfirmasi hingga ke bangunan (atau apartemen atau kotak pos). `partially_verified`: alamat hanya dikonfirmasi hingga ke jalan, atau hingga tingkat paling tepat yang dimiliki data referensi pos untuk tempat tersebut. `not_verified`: hanya wilayah atau kota yang cocok, atau tidak ada yang cocok. `unavailable`: validasi tidak dapat dijalankan (misalnya layanan referensi tidak merespons); validasi ini tidak dikenai biaya dan tidak pernah memengaruhi verifikasi."
          },
          "verification_level": {
            "type": "string",
            "nullable": true,
            "enum": [
              "administrative_area",
              "locality",
              "thoroughfare",
              "premise",
              "delivery_point",
              null
            ],
            "description": "Tingkat paling presisi yang dicocokkan dengan alamat. `null` jika tidak ada yang cocok atau `status` bernilai `unavailable`."
          },
          "address": {
            "type": "object",
            "nullable": true,
            "description": "Alamat yang dinormalisasi. `null` jika `status` adalah `unavailable`.",
            "properties": {
              "address_line_1": {
                "type": "string",
                "nullable": true,
                "description": "Baris pengiriman pertama, ditulis sesuai dengan format penulisan di negara tersebut.",
                "example": "1600 Amphitheatre Pkwy"
              },
              "address_line_2": {
                "type": "string",
                "nullable": true,
                "description": "Baris pengiriman kedua (apartemen, gedung, atau lingkungan sekitar), jika alamat memilikinya."
              },
              "city": {
                "type": "string",
                "nullable": true,
                "example": "Mountain View"
              },
              "region": {
                "type": "string",
                "nullable": true,
                "description": "Negara bagian, provinsi, atau wilayah.",
                "example": "CA"
              },
              "postal_code": {
                "type": "string",
                "nullable": true,
                "example": "94043-1351"
              },
              "country": {
                "type": "string",
                "nullable": true,
                "description": "Kode negara ISO 3166-1 alpha-2.",
                "example": "US"
              }
            }
          },
          "formatted_address": {
            "type": "string",
            "nullable": true,
            "description": "Alamat yang dinormalisasi dalam satu baris.",
            "example": "1600 Amphitheatre Pkwy, Mountain View CA 94043-1351"
          },
          "latitude": {
            "type": "number",
            "nullable": true,
            "example": 37.422022
          },
          "longitude": {
            "type": "number",
            "nullable": true,
            "example": -122.08429
          }
        }
      },
      "AddressValidationRequest": {
        "type": "object",
        "required": [
          "country"
        ],
        "description": "Satu alamat: dalam satu baris (`address`) atau sebagai kolom terstruktur dengan setidaknya `address_line_1`, tidak boleh keduanya.",
        "properties": {
          "address": {
            "type": "string",
            "maxLength": 500,
            "description": "Seluruh alamat dalam satu baris.",
            "example": "Paseo de la Castellana 259, 28046 Madrid"
          },
          "address_line_1": {
            "type": "string",
            "maxLength": 255,
            "description": "Jalan dan nomor.",
            "example": "1600 Amphitheatre Pkwy"
          },
          "address_line_2": {
            "type": "string",
            "maxLength": 255,
            "description": "Apartemen, suite, lantai, atau gedung."
          },
          "city": {
            "type": "string",
            "maxLength": 128,
            "description": "Kota atau lokalitas.",
            "example": "Mountain View"
          },
          "region": {
            "type": "string",
            "maxLength": 128,
            "description": "Negara bagian, provinsi, atau wilayah.",
            "example": "CA"
          },
          "postal_code": {
            "type": "string",
            "maxLength": 32,
            "example": "94043"
          },
          "country": {
            "type": "string",
            "maxLength": 3,
            "description": "Kode ISO 3166-1 alpha-2 atau alpha-3 dari negara alamat.",
            "example": "US"
          }
        }
      },
      "AddressValidationResponse": {
        "type": "object",
        "required": [
          "request_id",
          "address_validation",
          "created_at"
        ],
        "properties": {
          "request_id": {
            "type": "string",
            "format": "uuid",
            "description": "Pengenal permintaan ini; kutip ke tim dukungan. Tidak ada sesi yang dibuat."
          },
          "address_validation": {
            "$ref": "#/components/schemas/AddressValidationResult"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "TravelRuleWalletProofFailureReason": {
        "type": "string",
        "enum": [
          "",
          "SIGNATURE_INVALID",
          "SIGNATURE_UNSUPPORTED_SCHEME",
          "DEPOSIT_NOT_FOUND",
          "DEPOSIT_UNCONFIRMED",
          "DEPOSIT_LOOKUP_FAILED",
          "DEPOSIT_MISMATCH",
          "DEPOSIT_STALE",
          "TXID_REUSED",
          "CHAIN_UNSUPPORTED",
          "WINDOW_EXPIRED",
          "OWNERSHIP_CHANGED",
          "METHOD_SWITCHED",
          "REVIEW_REJECTED",
          "ABANDONED"
        ],
        "description": "Alasan mengapa bukti kepemilikan dompet, atau upaya terakhirnya, tidak mencapai VERIFIED. Kosong jika tidak ada yang gagal. Bukti PENDING dapat memuat alasan ini: upaya terakhir gagal dan pengguna akhir dapat mencoba lagi. DEPOSIT_MISMATCH, DEPOSIT_STALE, TXID_REUSED, dan REVIEW_REJECTED menutup bukti sebagai REJECTED. SIGNATURE_INVALID: tanda tangan tidak cocok dengan dompet dan tantangan. SIGNATURE_UNSUPPORTED_SCHEME: dompet menandatangani dalam format yang tidak diverifikasi Didit. DEPOSIT_NOT_FOUND, DEPOSIT_UNCONFIRMED, DEPOSIT_LOOKUP_FAILED: setoran uji tidak terbaca atau belum dikonfirmasi; Didit terus memeriksanya hingga jendela pengujian ditutup. DEPOSIT_MISMATCH: transaksi tidak mengirim jumlah yang diharapkan dari dompet ke alamat setoran. DEPOSIT_STALE: transaksi terjadi sebelum waktu tantangan. TXID_REUSED: transaksi telah membuktikan dompet lain. CHAIN_UNSUPPORTED: metode ini tidak tersedia pada rantai ini. WINDOW_EXPIRED: jendela pengujian telah ditutup. OWNERSHIP_CHANGED: pemegang dompet berubah, atau dompet dihapus dari buku alamat Anda, setelah sesi widget dibuat. METHOD_SWITCHED: pengguna akhir memilih metode lain sebelum menyelesaikan metode ini. REVIEW_REJECTED: peninjau Anda menolak tangkapan layar. ABANDONED: sesi widget berakhir sebelum pengguna akhir menyelesaikannya."
      },
      "TravelRuleWidgetProofError": {
        "type": "object",
        "properties": {
          "detail": {
            "type": "string",
            "description": "Pesan dalam bahasa Inggris yang mudah dibaca manusia."
          },
          "code": {
            "allOf": [
              {
                "$ref": "#/components/schemas/TravelRuleWalletProofFailureReason"
              }
            ],
            "description": "Alasan yang dapat dibaca mesin, agar klien dapat menampilkan pesan terjemahannya sendiri."
          },
          "status": {
            "type": "string",
            "enum": [
              "PENDING",
              "VERIFIED",
              "REJECTED",
              "EXPIRED"
            ],
            "description": "Hadir ketika bukti ditutup: REJECTED oleh deposit yang baru saja dikirimkan (400), atau REJECTED atau EXPIRED ketika bukti pendukung dikirimkan ke bukti yang sudah ditutup (409)."
          },
          "proof_id": {
            "type": "string",
            "format": "uuid",
            "description": "Hadir dengan status: bukti yang ditutup."
          },
          "method": {
            "type": "string",
            "enum": [
              "MESSAGE_SIGNING",
              "SATOSHI_TEST",
              "SCREENSHOT",
              "SELF_DECLARATION"
            ],
            "description": "Hadir dengan status: metode bukti yang ditutup."
          },
          "max_attempts": {
            "type": "integer",
            "description": "Hadir dengan status: bukti dompet yang ditolak yang diizinkan sesi ini."
          },
          "attempts_used": {
            "type": "integer",
            "description": "Hadir dengan status: bukti yang ditolak sejauh ini."
          },
          "attempts_remaining": {
            "type": "integer",
            "description": "Hadir dengan status: jika 0, memulai bukti lain akan menghasilkan 409 dan Anda perlu membuat sesi widget baru."
          }
        }
      },
      "TravelRuleWidgetProofCreate": {
        "type": "object",
        "required": [
          "method"
        ],
        "properties": {
          "method": {
            "type": "string",
            "enum": [
              "MESSAGE_SIGNING",
              "SATOSHI_TEST",
              "SCREENSHOT",
              "SELF_DECLARATION"
            ],
            "description": "Metode bukti yang dipilih pengguna akhir. Harus berupa salah satu dari allowed_methods milik konteks."
          },
          "wallet_address": {
            "type": "string",
            "maxLength": 128,
            "description": "Default-nya adalah wallet_address sesi. Harus cocok dengan dompet transfer saat sesi ditautkan ke suatu transfer."
          },
          "chain": {
            "type": "string",
            "maxLength": 32,
            "description": "Default-nya adalah blockchain sesi."
          }
        }
      },
      "TravelRuleWidgetProofVerifyResult": {
        "type": "object",
        "properties": {
          "proof_id": {
            "type": "string",
            "format": "uuid"
          },
          "method": {
            "type": "string",
            "enum": [
              "MESSAGE_SIGNING",
              "SATOSHI_TEST",
              "SCREENSHOT",
              "SELF_DECLARATION"
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "PENDING",
              "VERIFIED",
              "REJECTED",
              "EXPIRED"
            ]
          },
          "is_ownership_verified": {
            "type": "boolean",
            "description": "Hadir ketika bukti berstatus VERIFIED: entri buku alamat kini telah terverifikasi kepemilikannya."
          },
          "transfer_status": {
            "type": "string",
            "nullable": true,
            "description": "Hadir ketika bukti berstatus VERIFIED: status transfer tertaut, null jika tidak ada."
          },
          "detail": {
            "type": "string",
            "description": "Hadir selama bukti tetap PENDING: tangkapan layar yang dikirimkan menunggu peninjauan, atau deposit uji yang belum dikonfirmasi."
          },
          "code": {
            "allOf": [
              {
                "$ref": "#/components/schemas/TravelRuleWalletProofFailureReason"
              }
            ],
            "description": "Hadir pada deposit uji yang tertunda: alasan mengapa belum dikonfirmasi."
          }
        }
      },
      "TravelRuleWalletProofReview": {
        "type": "object",
        "properties": {
          "proof_id": {
            "type": "string",
            "format": "uuid"
          },
          "method": {
            "type": "string",
            "enum": [
              "SCREENSHOT"
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "PENDING",
              "VERIFIED",
              "REJECTED",
              "EXPIRED"
            ]
          },
          "wallet_address": {
            "type": "string"
          },
          "chain": {
            "type": "string",
            "description": "Pengenal blockchain kanonis, misalnya ETH, BTC, SOL, TRX."
          },
          "holder_name": {
            "type": "string"
          },
          "is_ownership_verified": {
            "type": "boolean",
            "description": "Apakah entri buku alamat diverifikasi kepemilikannya, melalui bukti ini atau yang lain."
          },
          "transaction_id": {
            "type": "string",
            "format": "uuid",
            "nullable": true,
            "description": "Transaksi tempat transfer Travel Rule dibuatkan sesi widget-nya. Null untuk sesi yang dibuat tanpa transaction_id."
          },
          "file_name": {
            "type": "string",
            "nullable": true
          },
          "content_type": {
            "type": "string",
            "nullable": true
          },
          "screenshot_url": {
            "type": "string",
            "nullable": true,
            "description": "Tautan dengan batas waktu ke tangkapan layar yang diunggah. Tampilkan antrean lagi untuk mendapatkan tautan baru."
          },
          "attempts": {
            "type": "integer",
            "description": "Berapa banyak file yang diunggah pengguna akhir untuk bukti ini."
          },
          "failure_reason": {
            "allOf": [
              {
                "$ref": "#/components/schemas/TravelRuleWalletProofFailureReason"
              }
            ],
            "description": "REVIEW_REJECTED setelah penolakan, OWNERSHIP_CHANGED saat dompet berganti pemilik atau dihapus sebelum keputusan diambil. Jika tidak, kosong."
          },
          "method_chosen_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Waktu ketika pengguna akhir memilih metode tangkapan layar."
          },
          "decided_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "decided_by": {
            "type": "string",
            "description": "Pihak yang menutup bukti: review:<user identifier> untuk peninjau konsol, review untuk keputusan kunci API, widget atau sweeper saat Didit menutupnya secara otomatis. Kosong selama PENDING."
          },
          "review_note": {
            "type": "string",
            "description": "Catatan yang dikirim bersama keputusan. Kosong jika tidak ada."
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "TravelRuleWalletProofDecision": {
        "type": "object",
        "required": [
          "decision"
        ],
        "properties": {
          "decision": {
            "type": "string",
            "enum": [
              "approve",
              "reject"
            ]
          },
          "note": {
            "type": "string",
            "maxLength": 512,
            "description": "Opsional. Disimpan bersama bukti dan dikembalikan sebagai review_note."
          }
        }
      },
      "DigitalIdWalletApiWalletDigitalCredentialsRequest": {
        "type": "object",
        "properties": {
          "protocol": {
            "type": "string",
            "description": "openid4vp-v1-signed."
          },
          "request": {
            "type": "object",
            "additionalProperties": {},
            "description": "Teruskan apa adanya: navigator.credentials.get({digital: request}) di browser, atau JSON.stringify(request) sebagai requestJson milik GetDigitalCredentialOption di Android. Ditandatangani oleh Didit untuk aplikasi Anda."
          }
        },
        "required": [
          "protocol",
          "request"
        ]
      },
      "DigitalIdWalletApiGoogleWalletWalletVerificationStartRequest": {
        "type": "object",
        "description": "Mulai verifikasi Google Wallet (USA, GBR, BRA, SGP, TWN).",
        "properties": {
          "vendor_data": {
            "type": "string",
            "nullable": true,
            "description": "Referensi Anda sendiri untuk verifikasi ini (mis. ID pengguna Anda). Dikembalikan dalam hasil dan webhook."
          },
          "metadata": {
            "type": "object",
            "additionalProperties": {},
            "nullable": true,
            "description": "Objek JSON opsional yang disimpan bersama verifikasi dan dikembalikan dalam hasil serta webhook."
          },
          "sandbox_scenario": {
            "type": "string",
            "minLength": 1,
            "description": "Khusus aplikasi sandbox: hasil simulasi - 'wallet_cancelled', 'wallet_timeout', atau 'wallet_provider_error'; skenario lain (atau tanpa skenario) akan lolos verifikasi. Ditolak pada aplikasi di lingkungan produksi. Katalog lengkap tersedia di GET /v1/sandbox/scenarios/."
          },
          "country": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DigitalIdWalletApiGoogleWalletWalletVerificationStartCountryEnum"
              }
            ],
            "description": "Negara ISO 3166-1 alpha-3 dari identitas Google Wallet.\n\n* `USA` - USA\n* `GBR` - GBR\n* `BRA` - BRA\n* `SGP` - SGP\n* `TWN` - TWN"
          },
          "origin": {
            "type": "string",
            "minLength": 1,
            "description": "Lokasi halaman atau aplikasi Anda akan meminta dompet: origin https dari halaman Anda (host-nya harus berada di allowed_return_hosts aplikasi, atau domain White Label miliknya), mis. https://app.example.com, atau android:apk-key-hash:<base64 SHA-256 dari sertifikat penandatanganan aplikasi Anda, tanpa padding>. Dompet menolak permintaan di tempat lain mana pun.",
            "maxLength": 256
          }
        },
        "required": [
          "country",
          "origin"
        ]
      },
      "DigitalIdWalletApiGoogleWalletWalletVerificationStartCountryEnum": {
        "enum": [
          "USA",
          "GBR",
          "BRA",
          "SGP",
          "TWN"
        ],
        "type": "string",
        "description": "* `USA` - USA\n* `GBR` - GBR\n* `BRA` - BRA\n* `SGP` - SGP\n* `TWN` - TWN"
      },
      "DigitalIdWalletApiWalletDigitalCredentialResponseRequest": {
        "type": "object",
        "description": "Jawaban dompet kepada halaman atau aplikasi Anda, untuk verifikasi ``request_digital_credential``.",
        "properties": {
          "response": {
            "type": "object",
            "additionalProperties": {},
            "description": "Persis seperti yang dikembalikan dompet: {protocol, data} dari DigitalCredential dari navigator.credentials.get, atau credentialJson yang diurai dari DigitalCredential Android. Dienkripsi ke Didit; jangan diubah."
          }
        },
        "required": [
          "response"
        ]
      },
      "SessionFilesExport": {
        "type": "object",
        "description": "Satu file ZIP berisi setiap file dari sebuah sesi, dalam kualitas asli.",
        "required": [
          "export_id",
          "session_id",
          "status",
          "file_count",
          "size_bytes",
          "download_url",
          "expires_at",
          "error",
          "created_at",
          "completed_at"
        ],
        "properties": {
          "export_id": {
            "type": "string",
            "format": "uuid",
            "description": "ID ekspor. Teruskan ke `GET /v3/session/{sessionId}/files-export/{exportId}/`."
          },
          "session_id": {
            "type": "string",
            "format": "uuid",
            "description": "Sesi asal file-file tersebut."
          },
          "status": {
            "type": "string",
            "enum": [
              "PENDING",
              "PROCESSING",
              "READY",
              "FAILED",
              "EXPIRED"
            ],
            "description": "`PENDING` dan `PROCESSING` saat ZIP sedang disiapkan, `READY` setelah dapat diunduh, `FAILED` ketika tidak dapat disiapkan (minta ekspor baru), `EXPIRED` setelah ZIP dihapus."
          },
          "file_count": {
            "type": "integer",
            "nullable": true,
            "description": "File di dalam ZIP. Diatur hanya ketika `status` bernilai `READY`."
          },
          "size_bytes": {
            "type": "integer",
            "format": "int64",
            "nullable": true,
            "description": "Ukuran ZIP dalam bita. Diatur hanya saat `status` adalah `READY`."
          },
          "download_url": {
            "type": "string",
            "format": "uri",
            "nullable": true,
            "description": "URL ZIP yang ditandatangani, valid untuk waktu singkat. Diatur hanya saat `status` adalah `READY`; baca ekspor lagi untuk mendapatkan yang baru."
          },
          "expires_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Waktu ketika ZIP dihapus, 24 jam setelah siap. Hanya diatur selama `status` bernilai `READY`."
          },
          "error": {
            "type": "string",
            "nullable": true,
            "description": "Alasan mengapa ekspor gagal, saat `status` adalah `FAILED`."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "Waktu ketika ekspor diminta."
          },
          "completed_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Waktu ketika ZIP siap atau ekspor gagal."
          }
        }
      },
      "TransactionRuleSuggestionsCreatedEvent": {
        "description": "Proses saran aturan transaksi mengusulkan perubahan aturan baru untuk aplikasi Anda. Dikirim saat pengaturan saran aturan mengaktifkan notifikasi webhook. Tidak ada `status` tingkat atas.",
        "allOf": [
          {
            "$ref": "#/components/schemas/WebhookEventEnvelope"
          },
          {
            "type": "object",
            "properties": {
              "webhook_type": {
                "type": "string",
                "enum": [
                  "transaction_rule_suggestions.created"
                ],
                "description": "Selalu `transaction_rule_suggestions.created`."
              },
              "run_id": {
                "type": "string",
                "format": "uuid",
                "description": "Eksekusi saran yang menghasilkan saran baru."
              },
              "open_count": {
                "type": "integer",
                "description": "Jumlah saran yang masih terbuka setelah eksekusi ini, termasuk yang baru."
              },
              "suggestions": {
                "type": "array",
                "description": "Saran yang dihasilkan oleh proses ini.",
                "items": {
                  "type": "object",
                  "required": [
                    "suggestion_id",
                    "kind",
                    "title",
                    "rule_id",
                    "expected_impact"
                  ],
                  "properties": {
                    "suggestion_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "kind": {
                      "type": "string",
                      "enum": [
                        "ADD",
                        "TWEAK",
                        "DISABLE"
                      ],
                      "description": "`ADD` mengusulkan aturan baru, `TWEAK` mengubah aturan yang ada, `DISABLE` menonaktifkan aturan."
                    },
                    "title": {
                      "type": "string"
                    },
                    "rule_id": {
                      "type": "string",
                      "format": "uuid",
                      "nullable": true,
                      "description": "Aturan yang menjadi sasaran saran `TWEAK` atau `DISABLE`; `null` untuk `ADD`."
                    },
                    "expected_impact": {
                      "type": "object",
                      "additionalProperties": true,
                      "description": "Apa yang akan dilakukan oleh perubahan tersebut, seperti yang ditunjukkan oleh saran di Console."
                    }
                  }
                }
              }
            },
            "required": [
              "webhook_type",
              "run_id",
              "open_count",
              "suggestions"
            ]
          }
        ]
      },
      "GeolocationCheck": {
        "type": "object",
        "description": "Satu hasil verifikasi Lokasi, upaya yang diterima dari satu node alur kerja. Pengukuran, ketidakpastian, dan keaslian adalah kunci terpisah, sehingga hasil penentuan lokasi yang presisi dan belum teratestasi terbaca secara berbeda dari hasil penentuan lokasi yang tidak presisi dan telah teratestasi.",
        "properties": {
          "node_id": {
            "type": "string",
            "nullable": true,
            "description": "Node alur kerja yang menghasilkan hasil ini, sehingga alur kerja dengan dua langkah verifikasi Lokasi tetap mudah dibaca."
          },
          "status": {
            "type": "string",
            "enum": [
              "Not Finished",
              "Approved",
              "Declined",
              "In Review",
              "Resub Requested"
            ],
            "description": "Status tingkat fitur dari langkah verifikasi Lokasi ini, ditentukan berdasarkan peringatannya. Tidak bergantung pada `status` sesi."
          },
          "outcome": {
            "type": "string",
            "nullable": true,
            "description": "Hal yang terjadi pada upaya ini.",
            "enum": [
              "verified",
              "low_accuracy",
              "accuracy_undetermined",
              "stale",
              "approximate",
              "denied",
              "restricted",
              "unavailable",
              "timeout",
              "mock_detected",
              "outside_geofence",
              "in_blocked_area",
              "anonymizer_detected",
              "skipped",
              "replay_rejected",
              "unsupported_client",
              null
            ]
          },
          "permission": {
            "type": "string",
            "nullable": true,
            "description": "Izin apa yang diberikan oleh sistem operasi atau browser. `not_requested` berarti langkah tersebut hanya menggunakan lokasi IP koneksi, sehingga orang tersebut tidak pernah dimintai izin.",
            "enum": [
              "granted_precise",
              "granted_approximate",
              "denied",
              "restricted",
              "unavailable",
              "timeout",
              "dismissed",
              "not_requested",
              null
            ]
          },
          "latitude": {
            "type": "number",
            "nullable": true,
            "description": "Lintang WGS84 dari lokasi. `null` jika tidak ada lokasi.",
            "format": "double"
          },
          "longitude": {
            "type": "number",
            "nullable": true,
            "description": "Bujur WGS84 dari lokasi. `null` jika tidak ada lokasi.",
            "format": "double"
          },
          "accuracy_m": {
            "type": "number",
            "nullable": true,
            "description": "Radius ketidakpastian dalam meter, sesuai tingkat keyakinan yang ditentukan dalam `accuracy_confidence`.",
            "format": "double"
          },
          "accuracy_confidence": {
            "type": "string",
            "nullable": true,
            "description": "Tingkat keyakinan yang ditetapkan platform ke `accuracy_m`: `p95` (browser), `p68` (Android), atau `unspecified` (iOS).",
            "enum": [
              "p95",
              "p68",
              "unspecified",
              null
            ]
          },
          "measured_at": {
            "type": "string",
            "nullable": true,
            "description": "Waktu ketika perangkat memperoleh posisi, menurut jamnya sendiri.",
            "format": "date-time"
          },
          "age_seconds": {
            "type": "integer",
            "nullable": true,
            "description": "Detik antara perangkat memperoleh data lokasi dan Didit menerimanya."
          },
          "source": {
            "type": "string",
            "nullable": true,
            "description": "Dari mana lokasi tersebut berasal, jika platform menyatakannya. `ip` berarti posisinya adalah lokasi IP koneksi.",
            "enum": [
              "gps",
              "fused",
              "network",
              "wifi",
              "cell",
              "browser",
              "unknown",
              "ip",
              null
            ]
          },
          "platform": {
            "type": "string",
            "nullable": true,
            "description": "Klien yang menghasilkan perbaikan tersebut.",
            "enum": [
              "web",
              "ios",
              "android",
              "react_native",
              "flutter",
              null
            ]
          },
          "sdk_version": {
            "type": "string",
            "nullable": true,
            "description": "Versi SDK yang menghasilkan perbaikan tersebut."
          },
          "is_mock": {
            "type": "boolean",
            "nullable": true,
            "description": "`true` saat perangkat menyatakan bahwa lokasi berasal dari penyedia lokasi tiruan atau perangkat lunak simulasi. `null` saat platform tidak melaporkannya (browser tidak dapat membedakannya); `null` bukan `false`."
          },
          "produced_by_accessory": {
            "type": "boolean",
            "nullable": true,
            "description": "Khusus iOS: `true` jika perbaikan berasal dari aksesori eksternal. `null` untuk kasus lainnya."
          },
          "integrity": {
            "type": "string",
            "enum": [
              "attested",
              "not_attested",
              "failed",
              "unsupported",
              "not_determined"
            ],
            "description": "Menentukan apakah atestasi perangkat mendukung perbaikan tersebut. `unsupported` adalah apa yang dilaporkan browser, karena web tidak memiliki mekanisme atestasi; ini bukan sebuah kegagalan."
          },
          "country_code": {
            "type": "string",
            "nullable": true,
            "description": "Negara ISO 3166-1 alpha-2 tempat perbaikan berada."
          },
          "region_code": {
            "type": "string",
            "nullable": true,
            "description": "Subdivisi ISO 3166-2 tempat perbaikan berada."
          },
          "city": {
            "type": "string",
            "nullable": true,
            "description": "Tempat berpenduduk terdekat, label untuk peninjau."
          },
          "geofence": {
            "type": "object",
            "description": "Hasil aturan negara dan wilayah dari langkah ini.",
            "properties": {
              "enabled": {
                "type": "boolean",
                "description": "Apakah langkah tersebut menerapkan aturan negara atau wilayah."
              },
              "result": {
                "type": "string",
                "nullable": true,
                "description": "Posisi relatif terhadap aturan. `undetermined` berarti lingkaran akurasi melintasi perbatasan atau posisi tidak terpetakan ke negara mana pun; ini bukan bukti berada di luar.",
                "enum": [
                  "inside",
                  "outside",
                  "undetermined",
                  null
                ]
              }
            }
          },
          "inside_geofence": {
            "type": "boolean",
            "nullable": true,
            "description": "`true` jika `geofence.result` adalah `inside`, `false` jika `outside`, `null` jika sebaliknya."
          },
          "geofence_basis": {
            "type": "string",
            "nullable": true,
            "description": "Posisi mana yang digunakan untuk menilai hasil area: posisi `device`, atau lokasi `ip` koneksi.",
            "enum": [
              "device",
              "ip",
              null
            ]
          },
          "inside_areas": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Id area yang diizinkan yang terkonfigurasi tempat posisi berada di dalamnya."
          },
          "blocked_areas": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Id area terblokir yang terkonfigurasi tempat posisi berada di dalamnya."
          },
          "position_source": {
            "type": "string",
            "nullable": true,
            "description": "Asal pengambilan posisi oleh langkah tersebut, sesuai konfigurasi: perangkat diperiksa terhadap lokasi IP, perangkat saja, atau lokasi IP saja.",
            "enum": [
              "device_and_ip",
              "device_only",
              "ip_only",
              null
            ]
          },
          "anonymizers": {
            "type": "object",
            "nullable": true,
            "description": "Seperti apa kondisi koneksi dan perangkat, masing-masing bernilai `true`, `false`, atau `null` jika sumber tidak dapat memastikannya.",
            "properties": {
              "vpn": {
                "type": "boolean",
                "nullable": true
              },
              "proxy": {
                "type": "boolean",
                "nullable": true
              },
              "tor": {
                "type": "boolean",
                "nullable": true
              },
              "spoofing": {
                "type": "boolean",
                "nullable": true
              },
              "emulator": {
                "type": "boolean",
                "nullable": true
              }
            }
          },
          "ip_distance_km": {
            "type": "number",
            "nullable": true,
            "description": "Jarak ke lokasi IP sesi setelah kedua radius ketidakpastian dikurangkan; `0` jika keduanya tumpang tindih.",
            "format": "double"
          },
          "ip_distance_uncertainty_km": {
            "type": "number",
            "nullable": true,
            "description": "Radius gabungan yang dikurangkan: radius lokasi IP ditambah akurasi penetapan lokasi ini.",
            "format": "double"
          },
          "ip_consistent": {
            "type": "boolean",
            "nullable": true,
            "description": "Menentukan apakah `ip_distance_km` berada dalam jarak yang dikonfigurasi pada langkah tersebut. `null` jika salah satu sisi tidak diketahui."
          },
          "document_distance_km": {
            "type": "number",
            "nullable": true,
            "description": "Jarak ke alamat ber-geocode pada dokumen identitas atau bukti alamat. `null` jika tidak ada alamat yang tersimpan.",
            "format": "double"
          },
          "travel_excused": {
            "type": "boolean",
            "nullable": true,
            "description": "Apakah toleransi perjalanan pada langkah tersebut memaklumi jarak dari alamat. Bernilai `null` saat toleransi dinonaktifkan."
          },
          "consecutive_mismatches": {
            "type": "integer",
            "nullable": true,
            "description": "Pada upaya terakhir: pemeriksaan ini ditambah ketidakcocokan sebelumnya dari orang yang sama secara berturut-turut."
          },
          "attempts": {
            "type": "integer",
            "description": "Nomor percobaan ini di dalam node, dimulai dari 1."
          },
          "consent": {
            "type": "object",
            "nullable": true,
            "description": "Persetujuan yang diberikan orang tersebut sebelum perintah sistem, dicatat bersama versi redaksi dan bahasa yang mereka lihat.",
            "properties": {
              "accepted_at": {
                "type": "string",
                "format": "date-time"
              },
              "version": {
                "type": "string",
                "nullable": true
              },
              "locale": {
                "type": "string",
                "nullable": true
              }
            }
          },
          "warnings": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "feature": {
                  "type": "string",
                  "enum": [
                    "ID_VERIFICATION",
                    "NFC",
                    "LIVENESS",
                    "FACEMATCH",
                    "PROOF_OF_ADDRESS",
                    "PHONE",
                    "EMAIL",
                    "AML",
                    "LOCATION",
                    "DATABASE_VALIDATION",
                    "QUESTIONNAIRE",
                    "DOCUMENT_AI",
                    "KYB_REGISTRY",
                    "KYB_DOCUMENTS",
                    "KYB_KEY_PEOPLE",
                    "GEOLOCATION",
                    "SIGNATURE"
                  ],
                  "description": "Fitur yang menghasilkan peringatan ini. Nilai ini mengidentifikasi blok fitur tempat peringatan tersebut berada. Array peringatan setiap modul biasanya menggunakan nilai yang cocok dengan modulnya (misalnya `PHONE` di dalam `phone_verifications[].warnings`), tetapi enum di atas bersifat otoritatif di semua peringatan fitur pada payload keputusan."
                },
                "risk": {
                  "type": "string"
                },
                "additional_data": {
                  "type": "object",
                  "nullable": true
                },
                "log_type": {
                  "type": "string"
                },
                "short_description": {
                  "type": "string"
                },
                "long_description": {
                  "type": "string"
                },
                "node_id": {
                  "type": "string",
                  "description": "ID node graf alur kerja yang menghasilkan peringatan ini"
                }
              }
            },
            "description": "Peringatan yang dimunculkan oleh langkah verifikasi Lokasi ini, dengan `feature` yang diatur ke `GEOLOCATION`. Kode peringatan dimulai dengan `LOCATION_`."
          }
        }
      },
      "GeolocationAttempt": {
        "type": "object",
        "description": "Satu percobaan langkah verifikasi Lokasi: kunci yang sama dengan `geolocation_checks[]` kecuali `warnings`, ditambah waktu saat Didit menerimanya.",
        "properties": {
          "node_id": {
            "type": "string",
            "nullable": true,
            "description": "Node alur kerja yang menghasilkan hasil ini, sehingga alur kerja dengan dua langkah verifikasi Lokasi tetap mudah dibaca."
          },
          "status": {
            "type": "string",
            "enum": [
              "Not Finished",
              "Approved",
              "Declined",
              "In Review",
              "Resub Requested"
            ],
            "description": "Status tingkat fitur dari langkah verifikasi Lokasi ini, ditentukan berdasarkan peringatannya. Tidak bergantung pada `status` sesi."
          },
          "outcome": {
            "type": "string",
            "nullable": true,
            "description": "Hal yang terjadi pada upaya ini.",
            "enum": [
              "verified",
              "low_accuracy",
              "accuracy_undetermined",
              "stale",
              "approximate",
              "denied",
              "restricted",
              "unavailable",
              "timeout",
              "mock_detected",
              "outside_geofence",
              "in_blocked_area",
              "anonymizer_detected",
              "skipped",
              "replay_rejected",
              "unsupported_client",
              null
            ]
          },
          "permission": {
            "type": "string",
            "nullable": true,
            "description": "Izin apa yang diberikan oleh sistem operasi atau browser. `not_requested` berarti langkah tersebut hanya menggunakan lokasi IP koneksi, sehingga orang tersebut tidak pernah dimintai izin.",
            "enum": [
              "granted_precise",
              "granted_approximate",
              "denied",
              "restricted",
              "unavailable",
              "timeout",
              "dismissed",
              "not_requested",
              null
            ]
          },
          "latitude": {
            "type": "number",
            "nullable": true,
            "description": "Lintang WGS84 dari lokasi. `null` jika tidak ada lokasi.",
            "format": "double"
          },
          "longitude": {
            "type": "number",
            "nullable": true,
            "description": "Bujur WGS84 dari lokasi. `null` jika tidak ada lokasi.",
            "format": "double"
          },
          "accuracy_m": {
            "type": "number",
            "nullable": true,
            "description": "Radius ketidakpastian dalam meter, sesuai tingkat keyakinan yang ditentukan dalam `accuracy_confidence`.",
            "format": "double"
          },
          "accuracy_confidence": {
            "type": "string",
            "nullable": true,
            "description": "Tingkat keyakinan yang ditetapkan platform ke `accuracy_m`: `p95` (browser), `p68` (Android), atau `unspecified` (iOS).",
            "enum": [
              "p95",
              "p68",
              "unspecified",
              null
            ]
          },
          "measured_at": {
            "type": "string",
            "nullable": true,
            "description": "Waktu ketika perangkat memperoleh posisi, menurut jamnya sendiri.",
            "format": "date-time"
          },
          "age_seconds": {
            "type": "integer",
            "nullable": true,
            "description": "Detik antara perangkat memperoleh data lokasi dan Didit menerimanya."
          },
          "source": {
            "type": "string",
            "nullable": true,
            "description": "Dari mana lokasi tersebut berasal, jika platform menyatakannya. `ip` berarti posisinya adalah lokasi IP koneksi.",
            "enum": [
              "gps",
              "fused",
              "network",
              "wifi",
              "cell",
              "browser",
              "unknown",
              "ip",
              null
            ]
          },
          "platform": {
            "type": "string",
            "nullable": true,
            "description": "Klien yang menghasilkan perbaikan tersebut.",
            "enum": [
              "web",
              "ios",
              "android",
              "react_native",
              "flutter",
              null
            ]
          },
          "sdk_version": {
            "type": "string",
            "nullable": true,
            "description": "Versi SDK yang menghasilkan perbaikan tersebut."
          },
          "is_mock": {
            "type": "boolean",
            "nullable": true,
            "description": "`true` saat perangkat menyatakan bahwa lokasi berasal dari penyedia lokasi tiruan atau perangkat lunak simulasi. `null` saat platform tidak melaporkannya (browser tidak dapat membedakannya); `null` bukan `false`."
          },
          "produced_by_accessory": {
            "type": "boolean",
            "nullable": true,
            "description": "Khusus iOS: `true` jika perbaikan berasal dari aksesori eksternal. `null` untuk kasus lainnya."
          },
          "integrity": {
            "type": "string",
            "enum": [
              "attested",
              "not_attested",
              "failed",
              "unsupported",
              "not_determined"
            ],
            "description": "Menentukan apakah atestasi perangkat mendukung perbaikan tersebut. `unsupported` adalah apa yang dilaporkan browser, karena web tidak memiliki mekanisme atestasi; ini bukan sebuah kegagalan."
          },
          "country_code": {
            "type": "string",
            "nullable": true,
            "description": "Negara ISO 3166-1 alpha-2 tempat perbaikan berada."
          },
          "region_code": {
            "type": "string",
            "nullable": true,
            "description": "Subdivisi ISO 3166-2 tempat perbaikan berada."
          },
          "city": {
            "type": "string",
            "nullable": true,
            "description": "Tempat berpenduduk terdekat, label untuk peninjau."
          },
          "geofence": {
            "type": "object",
            "description": "Hasil aturan negara dan wilayah dari langkah ini.",
            "properties": {
              "enabled": {
                "type": "boolean",
                "description": "Apakah langkah tersebut menerapkan aturan negara atau wilayah."
              },
              "result": {
                "type": "string",
                "nullable": true,
                "description": "Posisi relatif terhadap aturan. `undetermined` berarti lingkaran akurasi melintasi perbatasan atau posisi tidak terpetakan ke negara mana pun; ini bukan bukti berada di luar.",
                "enum": [
                  "inside",
                  "outside",
                  "undetermined",
                  null
                ]
              }
            }
          },
          "inside_geofence": {
            "type": "boolean",
            "nullable": true,
            "description": "`true` jika `geofence.result` adalah `inside`, `false` jika `outside`, `null` jika sebaliknya."
          },
          "geofence_basis": {
            "type": "string",
            "nullable": true,
            "description": "Posisi mana yang digunakan untuk menilai hasil area: posisi `device`, atau lokasi `ip` koneksi.",
            "enum": [
              "device",
              "ip",
              null
            ]
          },
          "inside_areas": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Id area yang diizinkan yang terkonfigurasi tempat posisi berada di dalamnya."
          },
          "blocked_areas": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Id area terblokir yang terkonfigurasi tempat posisi berada di dalamnya."
          },
          "position_source": {
            "type": "string",
            "nullable": true,
            "description": "Asal pengambilan posisi oleh langkah tersebut, sesuai konfigurasi: perangkat diperiksa terhadap lokasi IP, perangkat saja, atau lokasi IP saja.",
            "enum": [
              "device_and_ip",
              "device_only",
              "ip_only",
              null
            ]
          },
          "anonymizers": {
            "type": "object",
            "nullable": true,
            "description": "Seperti apa kondisi koneksi dan perangkat, masing-masing bernilai `true`, `false`, atau `null` jika sumber tidak dapat memastikannya.",
            "properties": {
              "vpn": {
                "type": "boolean",
                "nullable": true
              },
              "proxy": {
                "type": "boolean",
                "nullable": true
              },
              "tor": {
                "type": "boolean",
                "nullable": true
              },
              "spoofing": {
                "type": "boolean",
                "nullable": true
              },
              "emulator": {
                "type": "boolean",
                "nullable": true
              }
            }
          },
          "ip_distance_km": {
            "type": "number",
            "nullable": true,
            "description": "Jarak ke lokasi IP sesi setelah kedua radius ketidakpastian dikurangkan; `0` jika keduanya tumpang tindih.",
            "format": "double"
          },
          "ip_distance_uncertainty_km": {
            "type": "number",
            "nullable": true,
            "description": "Radius gabungan yang dikurangkan: radius lokasi IP ditambah akurasi penetapan lokasi ini.",
            "format": "double"
          },
          "ip_consistent": {
            "type": "boolean",
            "nullable": true,
            "description": "Menentukan apakah `ip_distance_km` berada dalam jarak yang dikonfigurasi pada langkah tersebut. `null` jika salah satu sisi tidak diketahui."
          },
          "document_distance_km": {
            "type": "number",
            "nullable": true,
            "description": "Jarak ke alamat ber-geocode pada dokumen identitas atau bukti alamat. `null` jika tidak ada alamat yang tersimpan.",
            "format": "double"
          },
          "travel_excused": {
            "type": "boolean",
            "nullable": true,
            "description": "Apakah toleransi perjalanan pada langkah tersebut memaklumi jarak dari alamat. Bernilai `null` saat toleransi dinonaktifkan."
          },
          "consecutive_mismatches": {
            "type": "integer",
            "nullable": true,
            "description": "Pada upaya terakhir: pemeriksaan ini ditambah ketidakcocokan sebelumnya dari orang yang sama secara berturut-turut."
          },
          "attempts": {
            "type": "integer",
            "description": "Nomor percobaan ini di dalam node, dimulai dari 1."
          },
          "consent": {
            "type": "object",
            "nullable": true,
            "description": "Persetujuan yang diberikan orang tersebut sebelum perintah sistem, dicatat bersama versi redaksi dan bahasa yang mereka lihat.",
            "properties": {
              "accepted_at": {
                "type": "string",
                "format": "date-time"
              },
              "version": {
                "type": "string",
                "nullable": true
              },
              "locale": {
                "type": "string",
                "nullable": true
              }
            }
          },
          "received_at": {
            "type": "string",
            "nullable": true,
            "description": "Waktu ketika Didit menerima upaya tersebut.",
            "format": "date-time"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "BiometricRetention": {
        "type": "object",
        "description": "Waktu data biometrik langsung dari sesi ini dihapus.",
        "required": [
          "jurisdictions",
          "deletes_at"
        ],
        "properties": {
          "jurisdictions": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Kode negara bagian AS yang aturan biometriknya menetapkan batas penghapusan untuk orang ini (`US` jika negara bagian tidak diketahui). Kosong jika tidak ada yang berlaku."
          },
          "deletes_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Tanggal data biometrik langsung (gambar wajah dan templat) sesi ini dihapus, berdasarkan pengaturan retensi aplikasi Anda dan, jika berlaku, batas hukum untuk yurisdiksi individu tersebut. `null` jika belum ada tanggal yang berlaku."
          }
        }
      },
      "TravelRuleManualMatchRequest": {
        "type": "object",
        "required": [
          "transaction_id"
        ],
        "properties": {
          "transaction_id": {
            "type": "string",
            "format": "uuid",
            "description": "`transaction_id` dari pesan Travel Rule yang diterima (baris dengan `kind: message`)."
          }
        }
      },
      "TravelRuleManualMatchResponse": {
        "type": "object",
        "required": [
          "deposit",
          "message"
        ],
        "properties": {
          "deposit": {
            "$ref": "#/components/schemas/TravelRuleTransferRow"
          },
          "message": {
            "$ref": "#/components/schemas/TravelRuleTransferRow"
          }
        }
      }
    },
    "securitySchemes": {
      "ApiKeyAuth": {
        "type": "apiKey",
        "in": "header",
        "name": "x-api-key",
        "description": "Kunci API aplikasi Anda, dari Developers -> API keys di Business Console. Kunci utama memiliki akses penuh. Kunci bernama dapat diberi cakupan: none, read, atau write per sumber daya, dibatasi pada beberapa alur kerja atau pada sesi yang disetujui, pada daftar alamat IP, dan pada tanggal kedaluwarsa. 401 berarti kuncinya salah, dicabut, atau kedaluwarsa; 403 berarti tidak ada kunci yang dikirimkan, kunci tidak memiliki akses ke sumber daya atau tindakan ini, atau permintaan datang dari alamat di luar daftar IP-nya; 404 pada rute sesi berarti sesi berada di luar alur kerja atau status kunci tersebut. Kunci tanpa akses media menerima URL gambar, video, dan PDF sebagai null, dan kunci tanpa izin tulis sesi menerima tautan sesi dan token sebagai null. Lihat https://docs.didit.me/console/api-keys."
      },
      "TransactionTokenAuth": {
        "type": "apiKey",
        "in": "header",
        "name": "X-Transaction-Token",
        "description": "Token berdurasi singkat dengan cakupan terbatas yang dicetak oleh backend Anda melalui POST /v3/transactions/sdk-token/. Digunakan oleh SDK Didit pada endpoint /v1/transactions/ yang digunakan perangkat."
      },
      "SessionTokenAuth": {
        "type": "apiKey",
        "in": "header",
        "name": "Session-Token",
        "description": "Token berdurasi singkat yang dikembalikan dalam kolom `session_token` pada POST /v3/session/. Digunakan oleh alur verifikasi yang di-hosting (dan UI sandbox kustom) untuk memanggil endpoint berlingkup sesi atas nama pengguna yang memverifikasi, tanpa kunci API sisi server Anda."
      },
      "BearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "Token akses client-credentials milik aplikasi."
      },
      "CaseRequestToken": {
        "type": "apiKey",
        "in": "header",
        "name": "X-Case-Request-Token",
        "description": "Kredensial khusus permintaan dari tautan aman. Hanya memberikan akses ke permintaan ini."
      }
    },
    "responses": {
      "Unauthorized": {
        "description": "Tidak diotorisasi",
        "content": {
          "application/json": {
            "examples": {
              "Invalid API Key": {
                "summary": "Kunci API tidak valid",
                "value": {
                  "detail": "Invalid API Key."
                }
              }
            }
          }
        }
      },
      "Forbidden": {
        "description": "Dilarang",
        "content": {
          "application/json": {
            "examples": {
              "No Permission": {
                "summary": "Tidak Ada Izin",
                "value": {
                  "detail": "You do not have permission to perform this action."
                }
              },
              "Not Enough Credits": {
                "summary": "Kredit Tidak Cukup",
                "value": {
                  "error": "You don't have enough credits to perform this request. Please top up at https://business.didit.me"
                }
              }
            }
          }
        }
      },
      "NotFound": {
        "description": "Tidak Ditemukan",
        "content": {
          "application/json": {
            "examples": {
              "Not Found": {
                "summary": "Tidak Ditemukan",
                "value": {
                  "detail": "Resource not found."
                }
              }
            }
          }
        }
      },
      "PhoneRiskValidationError": {
        "description": "Validasi permintaan gagal.",
        "content": {
          "application/json": {
            "examples": {
              "Missing phone number": {
                "summary": "Nomor telepon tidak ada",
                "value": {
                  "phone_number": [
                    "This field is required."
                  ]
                }
              },
              "Invalid phone number": {
                "summary": "Nomor telepon tidak valid",
                "value": {
                  "phone_number": [
                    "Invalid phone number provided."
                  ]
                }
              },
              "Invalid signal IP": {
                "summary": "IP sinyal tidak valid",
                "value": {
                  "signals": {
                    "ip": [
                      "Enter a valid IPv4 or IPv6 address."
                    ]
                  }
                }
              }
            }
          }
        }
      },
      "EmailRiskValidationError": {
        "description": "Validasi permintaan gagal.",
        "content": {
          "application/json": {
            "examples": {
              "Missing email": {
                "summary": "Email tidak ada",
                "value": {
                  "email": [
                    "This field is required."
                  ]
                }
              },
              "Invalid email": {
                "summary": "Email tidak valid",
                "value": {
                  "email": [
                    "Enter a valid email address."
                  ]
                }
              },
              "Invalid country hint": {
                "summary": "Petunjuk negara tidak valid",
                "value": {
                  "country_code": [
                    "Ensure this field has no more than 3 characters."
                  ]
                }
              }
            }
          }
        }
      },
      "IPRiskValidationError": {
        "description": "Validasi permintaan gagal.",
        "content": {
          "application/json": {
            "examples": {
              "Missing IP address": {
                "summary": "Alamat IP tidak ada",
                "value": {
                  "ip_address": [
                    "This field is required."
                  ]
                }
              },
              "Invalid IP address": {
                "summary": "Alamat IP tidak valid",
                "value": {
                  "ip_address": [
                    "Enter a valid IPv4 or IPv6 address."
                  ]
                }
              },
              "Country hint too long": {
                "summary": "Petunjuk negara terlalu panjang",
                "value": {
                  "claimed_country": [
                    "Ensure this field has no more than 3 characters."
                  ]
                }
              }
            }
          }
        }
      },
      "RiskPermissionDenied": {
        "description": "Kunci API tidak ada atau tidak valid, atau organisasi tidak dapat menanggung biaya pencarian langsung. API ini tidak pernah mengembalikan `401`.",
        "content": {
          "application/json": {
            "examples": {
              "Missing or invalid API key": {
                "summary": "Tidak ada header `x-api-key`, atau kunci tidak valid atau dicabut",
                "value": {
                  "detail": "You do not have permission to perform this action."
                }
              },
              "Not enough credits": {
                "summary": "Saldo organisasi tidak mencukupi untuk harga pencarian",
                "value": {
                  "error": "You don't have enough credits to perform this request."
                }
              }
            }
          }
        }
      },
      "RateLimitedWrite": {
        "description": "Batas tulis bersama sebesar 300 permintaan per menit per kunci API telah terlampaui. Patuhi `Retry-After` sebelum mencoba lagi.",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "required": [
                "detail"
              ],
              "properties": {
                "detail": {
                  "type": "string"
                }
              }
            },
            "example": {
              "detail": "Write request rate limit exceeded. You can make up to 300 requests per minute."
            }
          }
        }
      },
      "AddressValidationValidationError": {
        "description": "Body permintaan tidak valid: `country` tidak ada atau tidak dikenal, tidak ada alamat, atau menyertakan `address` sekaligus kolom terstruktur.",
        "content": {
          "application/json": {
            "examples": {
              "Unknown country": {
                "value": {
                  "country": [
                    "Use an ISO 3166-1 alpha-2 or alpha-3 country code, e.g. 'US' or 'USA'."
                  ]
                }
              },
              "No address": {
                "value": {
                  "address": [
                    "Send the address: 'address' on one line, or the structured fields with 'address_line_1'."
                  ]
                }
              },
              "Both shapes": {
                "value": {
                  "address": [
                    "Send either 'address' or the structured fields (address_line_1, ...), not both."
                  ]
                }
              }
            }
          }
        }
      },
      "AddressValidationPermissionDenied": {
        "description": "Kunci API tidak ada atau tidak valid, kunci dengan cakupan terbatas tidak memiliki akses tulis `sessions`, atau organisasi tidak dapat menanggung biaya validasi. API ini tidak pernah mengembalikan `401`.",
        "content": {
          "application/json": {
            "examples": {
              "Missing or invalid API key": {
                "value": {
                  "detail": "You do not have permission to perform this action."
                }
              },
              "Not enough credits": {
                "value": {
                  "detail": "You don't have enough credits to perform this request. Please top up at https://business.didit.me",
                  "code": "insufficient_credits"
                }
              }
            }
          }
        }
      },
      "DocumentProcessingBusy": {
        "description": "Terlalu banyak dokumen yang sedang diproses saat ini, sehingga unggahan ini tidak diproses: tidak ada yang disimpan dan tidak ada percobaan yang terpakai. Kirim kembali file yang sama setelah menunggu selama jumlah detik yang tercantum dalam `Retry-After`. Lakukan percabangan berdasarkan `code`, bukan pada teks pesan.",
        "headers": {
          "Retry-After": {
            "description": "Jumlah detik yang harus ditunggu sebelum mengirimkan permintaan yang sama lagi.",
            "schema": {
              "type": "integer",
              "example": 10
            }
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "required": [
                "detail",
                "code"
              ],
              "properties": {
                "detail": {
                  "type": "string"
                },
                "code": {
                  "type": "string",
                  "enum": [
                    "document_processing_busy"
                  ]
                }
              }
            },
            "example": {
              "detail": "We are busy processing documents. Please try again in a moment.",
              "code": "document_processing_busy"
            }
          }
        }
      }
    },
    "parameters": {
      "WebhookSignature": {
        "name": "X-Signature",
        "in": "header",
        "required": true,
        "schema": {
          "type": "string"
        },
        "description": "HMAC-SHA256 heksadesimal huruf kecil, dengan kunci rahasia tujuan, dari isi mentah permintaan yang tepat."
      },
      "WebhookSignatureV2": {
        "name": "X-Signature-V2",
        "in": "header",
        "required": true,
        "schema": {
          "type": "string"
        },
        "description": "HMAC-SHA256 heksadesimal huruf kecil, dengan kunci rahasia tujuan, dari JSON kanonikal isi permintaan (kunci diurutkan, tanpa spasi, karakter non-ASCII tidak di-escape). Direkomendasikan, karena tahan terhadap middleware yang melakukan re-encode isi permintaan."
      },
      "WebhookSignatureSimple": {
        "name": "X-Signature-Simple",
        "in": "header",
        "required": true,
        "deprecated": true,
        "schema": {
          "type": "string"
        },
        "description": "HMAC-SHA256 heksadesimal huruf kecil, dengan kunci rahasia tujuan, dari `{timestamp}:{session_id}:{status}:{webhook_type}` (kolom yang tidak ada sebagai string kosong). Hanya mencakup envelope, tidak pernah payload."
      },
      "WebhookTimestamp": {
        "name": "X-Timestamp",
        "in": "header",
        "required": true,
        "schema": {
          "type": "string"
        },
        "description": "Waktu Unix dalam detik, sama dengan `timestamp` pada body. Tolak pengiriman yang lebih lama dari beberapa menit."
      }
    }
  },
  "x-webhooks": {
    "status.updated": {
      "post": {
        "summary": "Status sesi berubah",
        "description": "Sesi verifikasi telah berubah status. `decision` hanya dikirim untuk `Approved`, `Declined`, `In Review`, dan `Abandoned`; bentuknya mengikuti `GET /v3/session/{sessionId}/decision/` untuk tujuan pada webhook versi 3 (default), dan bentuk ringkas versi lama untuk tujuan versi 1 atau 2. Sesi bisnis selalu menerima keputusan bisnis versi 3.",
        "tags": [
          "Webhook"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/WebhookSignature"
          },
          {
            "$ref": "#/components/parameters/WebhookSignatureV2"
          },
          {
            "$ref": "#/components/parameters/WebhookSignatureSimple"
          },
          {
            "$ref": "#/components/parameters/WebhookTimestamp"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SessionStatusUpdatedEvent"
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "Respons 2xx apa pun mengonfirmasi pengiriman. Respons lain dan waktu habis akan memicu percobaan ulang; lihat https://docs.didit.me/integration/webhooks."
          }
        }
      }
    },
    "data.updated": {
      "post": {
        "summary": "Data sesi berubah",
        "description": "Data sesi verifikasi berubah tanpa perubahan status, misalnya setelah pengeditan peninjauan manual, penggantian langkah, atau skrining ulang pemantauan berkelanjutan. `decision` hanya dikirimkan untuk `Approved`, `Declined`, `In Review`, dan `Abandoned`; nilainya memiliki bentuk `GET /v3/session/{sessionId}/decision/` untuk tujuan webhook versi 3 (default), dan bentuk ringkas yang lebih lama untuk tujuan versi 1 atau 2. Sesi bisnis selalu menerima keputusan bisnis versi 3.",
        "tags": [
          "Webhook"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/WebhookSignature"
          },
          {
            "$ref": "#/components/parameters/WebhookSignatureV2"
          },
          {
            "$ref": "#/components/parameters/WebhookSignatureSimple"
          },
          {
            "$ref": "#/components/parameters/WebhookTimestamp"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SessionDataUpdatedEvent"
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "Respons 2xx apa pun mengonfirmasi pengiriman. Respons lain dan waktu habis akan memicu percobaan ulang; lihat https://docs.didit.me/integration/webhooks."
          }
        }
      }
    },
    "user.status.updated": {
      "post": {
        "summary": "Status pengguna diubah",
        "description": "Pengguna mengubah status. Tidak dikirim saat pengguna dibuat.",
        "tags": [
          "Webhook"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/WebhookSignature"
          },
          {
            "$ref": "#/components/parameters/WebhookSignatureV2"
          },
          {
            "$ref": "#/components/parameters/WebhookSignatureSimple"
          },
          {
            "$ref": "#/components/parameters/WebhookTimestamp"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UserStatusUpdatedEvent"
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "Respons 2xx apa pun mengonfirmasi pengiriman. Respons lain dan waktu habis akan memicu percobaan ulang; lihat https://docs.didit.me/integration/webhooks."
          }
        }
      }
    },
    "user.data.updated": {
      "post": {
        "summary": "Data pengguna diubah",
        "description": "Kolom pada pengguna berubah. Tidak dikirim saat pengguna dibuat. Satu penyimpanan dapat menghasilkan event status dan data sekaligus.",
        "tags": [
          "Webhook"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/WebhookSignature"
          },
          {
            "$ref": "#/components/parameters/WebhookSignatureV2"
          },
          {
            "$ref": "#/components/parameters/WebhookSignatureSimple"
          },
          {
            "$ref": "#/components/parameters/WebhookTimestamp"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UserDataUpdatedEvent"
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "Respons 2xx apa pun mengonfirmasi pengiriman. Respons lain dan waktu habis akan memicu percobaan ulang; lihat https://docs.didit.me/integration/webhooks."
          }
        }
      }
    },
    "business.status.updated": {
      "post": {
        "summary": "Status bisnis berubah",
        "description": "Status bisnis berubah. Tidak dikirim saat bisnis dibuat.",
        "tags": [
          "Webhook"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/WebhookSignature"
          },
          {
            "$ref": "#/components/parameters/WebhookSignatureV2"
          },
          {
            "$ref": "#/components/parameters/WebhookSignatureSimple"
          },
          {
            "$ref": "#/components/parameters/WebhookTimestamp"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BusinessStatusUpdatedEvent"
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "Respons 2xx apa pun mengonfirmasi pengiriman. Respons lain dan waktu habis akan memicu percobaan ulang; lihat https://docs.didit.me/integration/webhooks."
          }
        }
      }
    },
    "business.data.updated": {
      "post": {
        "summary": "Data bisnis berubah",
        "description": "Kolom pada bisnis berubah. Tidak dikirim saat bisnis dibuat. Satu penyimpanan dapat menghasilkan event status dan data sekaligus.",
        "tags": [
          "Webhook"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/WebhookSignature"
          },
          {
            "$ref": "#/components/parameters/WebhookSignatureV2"
          },
          {
            "$ref": "#/components/parameters/WebhookSignatureSimple"
          },
          {
            "$ref": "#/components/parameters/WebhookTimestamp"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BusinessDataUpdatedEvent"
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "Respons 2xx apa pun mengonfirmasi pengiriman. Respons lain dan waktu habis akan memicu percobaan ulang; lihat https://docs.didit.me/integration/webhooks."
          }
        }
      }
    },
    "transaction.created": {
      "post": {
        "summary": "Transaksi dibuat",
        "description": "Transaksi dibuat dan diskrining. Hanya dikirim untuk aplikasi produksi.",
        "tags": [
          "Webhook"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/WebhookSignature"
          },
          {
            "$ref": "#/components/parameters/WebhookSignatureV2"
          },
          {
            "$ref": "#/components/parameters/WebhookSignatureSimple"
          },
          {
            "$ref": "#/components/parameters/WebhookTimestamp"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TransactionCreatedEvent"
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "Respons 2xx apa pun mengonfirmasi pengiriman. Respons lain dan waktu habis akan memicu percobaan ulang; lihat https://docs.didit.me/integration/webhooks."
          }
        }
      }
    },
    "transaction.status.updated": {
      "post": {
        "summary": "Status transaksi berubah",
        "description": "Status transaksi berubah, dari aturan, peninjauan, atau tindakan pengguna akhir. Hanya dikirim untuk aplikasi produksi.",
        "tags": [
          "Webhook"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/WebhookSignature"
          },
          {
            "$ref": "#/components/parameters/WebhookSignatureV2"
          },
          {
            "$ref": "#/components/parameters/WebhookSignatureSimple"
          },
          {
            "$ref": "#/components/parameters/WebhookTimestamp"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TransactionStatusUpdatedEvent"
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "Respons 2xx apa pun mengonfirmasi pengiriman. Respons lain dan waktu habis akan memicu percobaan ulang; lihat https://docs.didit.me/integration/webhooks."
          }
        }
      }
    },
    "travel_rule.status.updated": {
      "post": {
        "summary": "Status Travel Rule berubah",
        "description": "Pertukaran Travel Rule berubah status. Dikirim pada setiap transisi hingga dan termasuk `FINISHED`, `CANCELLED`, atau `EXPIRED`, tidak pernah setelahnya. Dikirim untuk aplikasi produksi dan, untuk pertukaran Travel Rule, untuk aplikasi sandbox juga (`environment: sandbox`). Tidak ada `status` tingkat atas.",
        "tags": [
          "Webhook"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/WebhookSignature"
          },
          {
            "$ref": "#/components/parameters/WebhookSignatureV2"
          },
          {
            "$ref": "#/components/parameters/WebhookSignatureSimple"
          },
          {
            "$ref": "#/components/parameters/WebhookTimestamp"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TravelRuleStatusUpdatedEvent"
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "Respons 2xx apa pun mengonfirmasi pengiriman. Respons lain dan waktu habis akan memicu percobaan ulang; lihat https://docs.didit.me/integration/webhooks."
          }
        }
      }
    },
    "workflow.compliance_changed": {
      "post": {
        "summary": "Kepatuhan alur kerja berubah",
        "description": "Status kepatuhan dari alur kerja yang dipublikasikan berubah setelah evaluasi ulang. Satu event per alur kerja. Tidak ada `status` tingkat atas.",
        "tags": [
          "Webhook"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/WebhookSignature"
          },
          {
            "$ref": "#/components/parameters/WebhookSignatureV2"
          },
          {
            "$ref": "#/components/parameters/WebhookSignatureSimple"
          },
          {
            "$ref": "#/components/parameters/WebhookTimestamp"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WorkflowComplianceChangedEvent"
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "Respons 2xx apa pun mengonfirmasi pengiriman. Respons lain dan waktu habis akan memicu percobaan ulang; lihat https://docs.didit.me/integration/webhooks."
          }
        }
      }
    },
    "kyb.registry_search.resolved": {
      "post": {
        "summary": "Pencarian perusahaan selesai (callback tanpa tanda tangan)",
        "description": "Isi callback yang dikirim ke `webhook_url` pada `POST /v3/kyb/search/` setelah pencarian registri selesai. Callback ini tidak ditandatangani: permintaan membawa `X-Didit-Unsigned-Callback: true` dan tidak menyertakan header tanda tangan apa pun, jadi konfirmasikan dengan mencocokkan `request_id` terhadap pencarian yang Anda mulai. Menggunakan `event_type`, bukan `webhook_type`.",
        "tags": [
          "Webhook"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/KYBRegistrySearchResolvedCallback"
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "Respons 2xx apa pun mengonfirmasi pengiriman. Respons lain dan waktu habis akan memicu percobaan ulang; lihat https://docs.didit.me/integration/webhooks."
          }
        }
      }
    },
    "transaction_rule_suggestions.created": {
      "post": {
        "summary": "Saran aturan transaksi dibuat",
        "description": "Proses saran aturan transaksi mengusulkan perubahan aturan baru untuk aplikasi Anda. Dikirim saat pengaturan saran aturan mengaktifkan notifikasi webhook. Tidak ada `status` tingkat atas.",
        "tags": [
          "Webhook"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/WebhookSignature"
          },
          {
            "$ref": "#/components/parameters/WebhookSignatureV2"
          },
          {
            "$ref": "#/components/parameters/WebhookSignatureSimple"
          },
          {
            "$ref": "#/components/parameters/WebhookTimestamp"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TransactionRuleSuggestionsCreatedEvent"
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "Respons 2xx apa pun mengonfirmasi pengiriman. Respons lain dan waktu habis akan memicu percobaan ulang; lihat https://docs.didit.me/integration/webhooks."
          }
        }
      }
    }
  }
}
