> ## Documentation Index
> Fetch the complete documentation index at: https://docs.didit.me/llms.txt
> Use this file to discover all available pages before exploring further.

# Integrasi API Verifikasi Identitas: Panduan Alur Lengkap

> Integrasi REST API Didit dari awal hingga akhir: dapatkan kredensial, buat sesi, bagikan tautan, tangani webhook, dan ambil keputusan KYC dalam hitungan menit.

Panduan ini memandu Anda melalui alur lengkap untuk mengintegrasikan verifikasi identitas Didit melalui REST API: mendapatkan kredensial, membuat sesi, menampilkannya kepada pengguna, dan menerima hasilnya.

***

## Langkah 1: Dapatkan Kredensial Anda

Ada dua cara untuk memperoleh `api_key`:

### Opsi A: Pendaftaran secara programatik (tanpa browser)

Cocok untuk CI/CD dan agen AI. Dua panggilan API, yaitu `POST /programmatic/register/` lalu `POST /programmatic/verify-email/`, akan mengembalikan `api_key` secara langsung.

→ Lihat [Pendaftaran Programmatic](https://docs.didit.me/id/integration/programmatic-registration.md) untuk alur lengkap, aturan kata sandi, masa berlaku JWT, dan kebijakan penguncian.

### Opsi B: Dari Didit Console

1. Buka [Didit Console](https://business.didit.me).
2. Buat atau pilih organisasi Anda.
3. Buka **Pengaturan** → **API & Webhook**.
4. Salin:
   * **Kunci API**: digunakan sebagai header `x-api-key` pada setiap panggilan verifikasi.
   * **Kunci Rahasia Webhook**: digunakan untuk memverifikasi tanda tangan HMAC webhook.

### Variabel lingkungan

```bash theme={null}
# Required
DIDIT_API_KEY=your_api_key_here
DIDIT_WEBHOOK_SECRET=your_webhook_secret_here

# Your workflow ID (from the Console)
DIDIT_WORKFLOW_ID=your_workflow_id_here
```

***

## Langkah 2: Buat Alur Kerja

Sebelum membuat sesi, Anda memerlukan alur kerja verifikasi. Alur kerja menentukan langkah verifikasi apa saja yang dilalui pengguna.

### Buat di Console

1. Buka [Didit Console](https://business.didit.me) → **Alur kerja**
2. Klik **Buat Alur Kerja**
3. Pilih templat dasar:

| Templat | Paling Cocok Untuk |
| - | - |
| **KYC** | Verifikasi identitas lengkap dengan dokumen ID |
| **Verifikasi Usia Adaptif** | Verifikasi usia dengan cadangan ID opsional |
| **Autentikasi Biometrik** | Verifikasi ulang pengguna yang kembali |
| **Verifikasi Alamat** | Verifikasi bukti alamat |

4. Tambahkan fitur opsional:

| Fitur | Deskripsi |
| - | - |
| Verifikasi NFC | Membaca data chip paspor/ID |
| Deteksi Liveness | Mencegah spoofing dengan video swafoto |
| Pencocokan Wajah | Mencocokkan swafoto dengan foto di dokumen |
| Verifikasi Telepon | Memverifikasi nomor telepon melalui SMS |
| Verifikasi Email | Memverifikasi alamat email |
| Skrining AML | Memeriksa berdasarkan daftar sanksi/PEP |
| Validasi Database | Memverifikasi berdasarkan database pemerintah |
| Analisis Perangkat & IP | Mendeteksi VPN, proxy, dan geolokasi |

5. Salin **ID Alur Kerja** Anda.

> [!NOTE]
>
> Lihat [Dokumentasi Alur Kerja](https://docs.didit.me/id/console/workflows.md) untuk opsi konfigurasi yang lebih rinci.

***

## Langkah 3: Buat Sesi Verifikasi

Panggil API untuk membuat sesi bagi pengguna Anda.

### Permintaan

```bash theme={null}
curl -X POST https://verification.didit.me/v3/session/ \
  -H "Content-Type: application/json" \
  -H "x-api-key: YOUR_API_KEY" \
  -d '{
    "workflow_id": "your-workflow-id",
    "callback": "https://yourapp.com/verification-complete",
    "vendor_data": "user-123"
  }'
```

### Parameter Permintaan

| Parameter | Wajib | Deskripsi |
| - | - | - |
| `workflow_id` | Ya | UUID alur kerja Anda dari Konsol. |
| `callback` | Tidak | URL tempat pengguna diarahkan setelah verifikasi. Didit menambahkan `verificationSessionId` dan `status` sebagai parameter query. Mendukung skema kustom (misalnya `myapp://`). Jika dihilangkan, akan menggunakan URL callback yang dikonfigurasi pada alur kerja. |
| `callback_method` | Tidak | Perangkat yang menangani pengalihan: `initiator`, `completer`, atau `both`. Bawaan: `initiator`. |
| `vendor_data` | Tidak | ID pengguna internal Anda, dikembalikan dalam webhook untuk korelasi. |
| `metadata` | Tidak | Objek JSON bebas yang disimpan bersama sesi dan dikembalikan dalam webhook. |
| `language` | Tidak | Petunjuk bahasa antarmuka (ISO 639-1, misalnya `en`, `es`). Bahasa peramban dideteksi otomatis jika dihilangkan. |
| `contact_details` | Tidak | Email/telepon pengguna untuk pengisian otomatis dan notifikasi email. |
| `expected_details` | Tidak | Detail pengguna yang diharapkan untuk validasi silang dengan data yang terverifikasi. |
| `portrait_image` | Kondisional | Gambar wajah dalam format Base64 (maksimal 2MB; JPEG, PNG, WebP, atau TIFF). Wajah referensi untuk alur kerja Autentikasi Biometrik atau yang mendahulukan Pencocokan Wajah. Bersifat opsional jika pengguna yang diidentifikasi oleh `vendor_data` sudah memiliki wajah tersimpan (wajah liveness yang disetujui, foto ePassport, potret dokumen identitas, atau wajah profil yang terdaftar): Didit menggunakannya kembali secara otomatis; `400` jika tidak ada yang tersedia. |
| `sandbox_scenario` | Tidak | Slug skenario khusus sandbox (misalnya `approve`, `decline_aml_hit`) yang mengisi sesi secara otomatis dengan input khusus. |

### Contoh Lengkap dengan Semua Opsi

```bash theme={null}
curl -X POST https://verification.didit.me/v3/session/ \
  -H "Content-Type: application/json" \
  -H "x-api-key: YOUR_API_KEY" \
  -d '{
    "workflow_id": "11111111-2222-3333-4444-555555555555",
    "callback": "https://yourapp.com/verification-complete",
    "vendor_data": "user-123",
    "metadata": {
      "plan": "premium",
      "signup_source": "mobile-app"
    },
    "contact_details": {
      "email": "alex.sample@example.com",
      "email_lang": "en",
      "send_notification_emails": true,
      "phone": "+15550101000"
    },
    "expected_details": {
      "first_name": "John",
      "last_name": "Doe",
      "date_of_birth": "1990-01-01",
      "expected_document_types": ["P", "ID"]
    }
  }'
```

> [!NOTE]
>
> `expected_details.expected_document_types` membatasi langkah verifikasi identitas
> hanya pada jenis dokumen tertentu. Layar pemilihan dokumen hanya menampilkan
> jenis yang diminta. Nilai yang diizinkan: `P` (paspor), `ID` (kartu identitas
> nasional), `DL` (surat izin mengemudi), `RP` (izin tinggal), `HIC` (kartu
> asuransi kesehatan), `TC` (kartu pajak), `SSC` (kartu jaminan sosial). Nilai
> tidak peka huruf besar-kecil dan duplikat dihapus; nilai yang tidak dikenali
> akan mengembalikan `400`. Lihat [Referensi Pembuatan Sesi](https://docs.didit.me/id/sessions-api/create-session.md) untuk skema lengkap.

### Respons

`201 Created`:

```json theme={null}
{
  "session_id": "11111111-2222-3333-4444-555555555555",
  "session_number": 43762,
  "session_token": "3FaJ9wLqX2Mz",
  "url": "https://verify.didit.me/session/3FaJ9wLqX2Mz",
  "vendor_data": "user-123",
  "metadata": {
    "plan": "premium",
    "signup_source": "mobile-app"
  },
  "status": "Not Started",
  "workflow_id": "11111111-2222-3333-4444-555555555555",
  "workflow_version": 3,
  "callback": "https://yourapp.com/verification-complete"
}
```

### Kolom Respons Utama

| Kolom | Deskripsi |
| - | - |
| `session_id` | UUID unik untuk sesi ini. Gunakan untuk `GET /v3/session/{sessionId}/decision/` dan webhook. |
| `session_number` | Nomor urut yang mudah dibaca dan ditampilkan di konsol Didit. |
| `session_token` | Token 12 karakter yang aman untuk URL, yang mengizinkan pengguna akhir membuka alur yang di-hosting serta menginisialisasi SDK native (SDK web menggunakan `url` sebagai gantinya). Perlakukan sebagai rahasia. |
| `url` | URL verifikasi yang di-hosting untuk mengalihkan pengguna, atau untuk disematkan dalam iframe. (Nama kolom adalah `url`, bukan `verification_url`.) Jika permintaan menyertakan `language`, URL berisi segmen jalur bahasa, misalnya `https://verify.didit.me/en/session/3FaJ9wLqX2Mz`. |
| `status` | Status saat ini: `"Not Started"` untuk sesi yang baru dibuat. |
| `workflow_id` | Pengenal alur kerja yang stabil tempat sesi berjalan. |
| `workflow_version` | Versi alur kerja yang dipublikasikan dan ditetapkan untuk sesi saat dibuat. |

> [!NOTE]
>
> **Idempotensi.** Jika `vendor_data` disertakan dan sudah ada sesi yang belum selesai
> (`Not Started`, `In Progress`, `Resubmitted`, atau `Awaiting User`) dengan
> `vendor_data` yang sama pada versi alur kerja terbaru yang dipublikasikan, sesi
> yang ada tersebut akan dikembalikan (tetap `201`) alih-alih membuat duplikat. Nilai
> `callback` dan `metadata` sesi tersebut diperbarui ke nilai baru, dan `status`
> mencerminkan sesi yang ada.

> [!NOTE]
>
> **Jika `x-api-key` tidak ada, akan dikembalikan `403`**
> dengan `{"detail": "You do not have permission to perform this action."}`, sama
> dengan respons untuk kunci yang valid tetapi tidak memiliki izin. Kunci yang salah,
> dicabut, atau kedaluwarsa akan mengembalikan `401`. Kredit yang tidak cukup
> mengembalikan `400`. Lihat [Referensi API Pembuatan Sesi](https://docs.didit.me/id/sessions-api/create-session.md) untuk
> dokumentasi lengkap.

***

## Langkah 4: Tampilkan Verifikasi kepada Pengguna

Pilih cara menampilkan alur verifikasi kepada pengguna Anda:

### Opsi A: SDK Native (direkomendasikan untuk mobile)

Gunakan `session_token` dengan SDK native untuk integrasi kamera, NFC, dan biometrik.

→ [SDK iOS](https://docs.didit.me/id/integration/native-sdks/ios-sdk.md) · [SDK Android](https://docs.didit.me/id/integration/native-sdks/android-sdk.md) · [React Native](https://docs.didit.me/id/integration/native-sdks/react-native-sdk.md) · [Flutter](https://docs.didit.me/id/integration/native-sdks/flutter-sdk.md)

### Opsi B: iframe InContext (direkomendasikan untuk web)

Sematkan verifikasi di halaman Anda menggunakan `url` yang dikembalikan pada Langkah 3.

```html theme={null}
<iframe
  src="{url}"
  style="width: 100%; height: 700px; border: none;"
  allow="camera; microphone; geolocation; clipboard-write; fullscreen; autoplay; encrypted-media; digital-credentials-get"
></iframe>
```

→ [iframe InContext](https://docs.didit.me/id/integration/web-sdks/incontext-iframe.md)

### Opsi C: Pengalihan

Alihkan pengguna ke URL verifikasi.

```javascript theme={null}
window.location.href = session.url;
```

→ [Pengalihan web](https://docs.didit.me/id/integration/web-sdks/web-redirect.md)

### Opsi D: WebView Mobile

Untuk aplikasi mobile tanpa SDK native.

```jsx theme={null}
// React Native
<WebView source={{ uri: session.url }} />
```

→ [WebView di iOS/Android](https://docs.didit.me/id/integration/web-sdks/webview-in-ios-android.md)

***

## Langkah 5: Menerima Hasil

### Melalui Webhook (Direkomendasikan)

Webhook memberi tahu server Anda secara waktu nyata saat status verifikasi berubah.

**Pengaturan:**

1. Buat tujuan webhook di [Console](https://business.didit.me) (**API & Webhook**) atau melalui [`POST /v3/webhook/destinations/`](https://docs.didit.me/id/management-api/webhook/create-destination) dengan `webhook_version: "v3"` dan array `subscribed_events` (misalnya `["status.updated"]`)
2. Simpan `secret_shared_key` yang dikembalikan saat pembuatan: kunci ini adalah rahasia HMAC untuk semua varian tanda tangan
3. Terapkan endpoint webhook di server Anda

**Contoh payload webhook:**

Di dalam `decision`, setiap hasil per fitur dikirim sebagai **array jamak** (`id_verifications[]`, `nfc_verifications[]`, `liveness_checks[]`, `face_matches[]`, …), satu entri untuk setiap node dalam alur kerja. Ini adalah kontrak V3 dan bersifat tetap: jangan pernah menulis kode yang bergantung pada kunci tunggal `nfc` / `id_verification` / `liveness`.

```json theme={null}
{
  "event_id": "9c0c8b8a-1111-4222-9333-444444444444",
  "webhook_type": "status.updated",
  "timestamp": 1774970000,
  "created_at": 1774969994,
  "application_id": "11111111-2222-3333-4444-555555555555",
  "environment": "live",
  "session_id": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee",
  "status": "Approved",
  "workflow_id": "22222222-3333-4444-5555-666666666666",
  "workflow_version": 4,
  "vendor_data": "user-123",
  "metadata": { "plan": "premium" },
  "decision": {
    "session_id": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee",
    "status": "Approved",
    "id_verifications": [
      { "node_id": "id_verification_1", "status": "Approved", "document_type": "Passport", "warnings": [] }
    ],
    "liveness_checks": [
      { "node_id": "liveness_1", "status": "Approved", "method": "PASSIVE", "score": 95.4, "warnings": [] }
    ],
    "face_matches": [
      { "node_id": "face_match_1", "status": "Approved", "score": 96.1, "warnings": [] }
    ],
    "reviews": []
  }
}
```

Objek `decision` hanya ada saat `status` bernilai `Approved`, `Declined`, `In Review`, atau `Abandoned` (event `Resubmitted` membawa `resubmit_info` sebagai gantinya). Didit menggunakan `event_id` yang sama di seluruh percobaan ulang dan tujuan distribusi, jadi gunakan itu sebagai kunci idempotensi Anda. Lihat [Model data](https://docs.didit.me/id/reference/data-models.md) untuk setiap array jamak dan kolom.

**Verifikasi tanda tangan (X-Signature-V2, direkomendasikan):**

`X-Signature-V2` adalah HMAC-SHA256 atas penyandian ulang kanonis dari badan JSON: float dengan nilai utuh diubah menjadi integer, kunci diurutkan secara rekursif, pemisah ringkas, dan Unicode dipertahankan.

```javascript theme={null}
const crypto = require("crypto");

// Match Didit's float normalisation: whole-valued floats serialise as ints.
function shortenFloats(data) {
  if (Array.isArray(data)) return data.map(shortenFloats);
  if (data !== null && typeof data === "object") {
    return Object.fromEntries(
      Object.entries(data).map(([key, value]) => [key, shortenFloats(value)])
    );
  }
  return data;
}

// Sort object keys recursively before re-stringifying.
function sortKeys(obj) {
  if (Array.isArray(obj)) return obj.map(sortKeys);
  if (obj !== null && typeof obj === "object") {
    return Object.keys(obj).sort().reduce((acc, key) => {
      acc[key] = sortKeys(obj[key]);
      return acc;
    }, {});
  }
  return obj;
}

function verifyWebhook(rawBody, signatureV2, timestamp, secret) {
  // 1. Reject anything older than 5 minutes
  const now = Math.floor(Date.now() / 1000);
  if (Math.abs(now - parseInt(timestamp, 10)) > 300) return false;

  // 2. Recompute HMAC-SHA256 against the canonical JSON Didit signs
  const canonical = JSON.stringify(sortKeys(shortenFloats(JSON.parse(rawBody))));
  const expected = crypto.createHmac("sha256", secret).update(canonical, "utf8").digest("hex");

  // 3. Constant-time compare
  const a = Buffer.from(expected, "utf8");
  const b = Buffer.from(signatureV2, "utf8");
  return a.length === b.length && crypto.timingSafeEqual(a, b);
}
```

→ [Dokumentasi webhook lengkap](https://docs.didit.me/id/integration/webhooks.md), termasuk `X-Signature` berbasis byte mentah, `X-Signature-Simple` yang sudah usang dan hanya memeriksa envelope pembungkus, serta cara memilih di antara keduanya. Didit mencoba ulang pengiriman yang gagal (`5xx`, `404`, timeout) hingga 2 kali (sekitar 1 menit, lalu sekitar 4 menit) dan menghentikan pengiriman setelah **5 detik**. Pastikan server Anda segera mengembalikan `2xx`.

### Melalui API (opsional)

Ambil payload keputusan yang sama kapan saja:

```bash theme={null}
curl https://verification.didit.me/v3/session/{session_id}/decision/ \
  -H "x-api-key: YOUR_API_KEY"
```

Bentuk respons (array jamak) identik dengan objek `decision` di dalam payload webhook, dan endpoint ini dapat dipanggil pada titik mana pun dalam siklus hidup sesi. Gunakan webhook untuk pembaruan real-time dan sisakan panggilan API untuk pengisian data susulan, audit, dan pembangunan ulang. Endpoint `/decision/` dibatasi 600 permintaan GET per menit per kunci API (lihat [Batas laju](https://docs.didit.me/id/integration/rate-limiting.md)). Untuk semantik error: `session_id` yang tidak dikenal mengembalikan `404` dengan `{"detail": "Not found."}`, kegagalan autentikasi muncul sebagai `403`, dan endpoint ini tidak pernah mengembalikan `401`. URL media dalam respons adalah tautan yang ditandatangani sebelumnya dan berumur pendek, jadi ambil segera dan jangan menyimpannya.

→ [Referensi API untuk mengambil sesi](https://docs.didit.me/id/sessions-api/retrieve-session.md)

***

## Contoh Kode Lengkap

### Node.js / Express

```javascript theme={null}
const express = require("express");
const crypto = require("crypto");
const app = express();

// Create verification session
app.post("/api/verify", async (req, res) => {
  const { userId } = req.body;

  const response = await fetch("https://verification.didit.me/v3/session/", {
    method: "POST",
    headers: {
      "x-api-key": process.env.DIDIT_API_KEY,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      workflow_id: process.env.DIDIT_WORKFLOW_ID,
      callback: `${process.env.APP_URL}/verification-complete`,
      vendor_data: userId,
    }),
  });

  const session = await response.json();

  // Store session_id associated with user
  await db.users.update({
    where: { id: userId },
    data: { verificationSessionId: session.session_id },
  });

  res.json({
    verificationUrl: session.url,             // hosted verification URL
    sessionToken: session.session_token,      // for native/web SDKs
  });
});

// Handle webhook — uses verifyWebhook / shortenFloats / sortKeys from Step 5
app.post(
  "/api/webhook",
  express.raw({ type: "application/json" }),
  (req, res) => {
    const signature = req.get("X-Signature-V2");
    const timestamp = req.get("X-Timestamp");

    if (
      !verifyWebhook(
        req.body.toString("utf8"),
        signature,
        timestamp,
        process.env.DIDIT_WEBHOOK_SECRET,
      )
    ) {
      return res.status(401).json({ error: "Invalid signature" });
    }

    const payload = JSON.parse(req.body);
    const { event_id, session_id, status, vendor_data } = payload;

    // Idempotency: the same event_id is reused on retries and fan-out.
    // Skip events you have already processed (e.g. a processed_events table).

    // Update user's verification status (status values are case-sensitive strings)
    if (status === "Approved") {
      db.users.update({
        where: { id: vendor_data },
        data: { isVerified: true, verifiedAt: new Date() },
      });
    }

    // Return 2xx quickly (Didit's delivery timeout is 5s); do heavy work asynchronously
    res.json({ received: true });
  },
);

app.listen(3000);
```

### Python / FastAPI

```python theme={null}
from fastapi import FastAPI, Request, HTTPException
import httpx
import hashlib
import hmac
import json
import os
import time

app = FastAPI()

@app.post("/api/verify")
async def create_verification(user_id: str):
    async with httpx.AsyncClient() as client:
        response = await client.post(
            "https://verification.didit.me/v3/session/",
            headers={
                "x-api-key": os.environ["DIDIT_API_KEY"],
                "Content-Type": "application/json"
            },
            json={
                "workflow_id": os.environ["DIDIT_WORKFLOW_ID"],
                "callback": f"{os.environ['APP_URL']}/verification-complete",
                "vendor_data": user_id
            }
        )

    session = response.json()
    return {
        "verification_url": session["url"],            # hosted verification URL
        "session_token": session["session_token"],     # for native/web SDKs
    }

def shorten_floats(data):
    """Match Didit: whole-valued floats serialise as ints."""
    if isinstance(data, dict):
        return {k: shorten_floats(v) for k, v in data.items()}
    if isinstance(data, list):
        return [shorten_floats(x) for x in data]
    if isinstance(data, float) and data.is_integer():
        return int(data)
    return data

@app.post("/api/webhook")
async def handle_webhook(request: Request):
    payload = await request.json()
    signature = request.headers.get("X-Signature-V2")
    timestamp = request.headers.get("X-Timestamp")

    # Verify timestamp freshness
    if not signature or not timestamp or abs(int(time.time()) - int(timestamp)) > 300:
        raise HTTPException(status_code=401, detail="Request too old")

    # Recompute Didit's V2 canonical JSON: shortened floats, sorted keys,
    # compact separators, Unicode preserved (ensure_ascii=False)
    canonical = json.dumps(
        shorten_floats(payload),
        sort_keys=True,
        separators=(",", ":"),
        ensure_ascii=False,
    )
    expected = hmac.new(
        os.environ["DIDIT_WEBHOOK_SECRET"].encode("utf-8"),
        canonical.encode("utf-8"),
        hashlib.sha256
    ).hexdigest()

    if not hmac.compare_digest(signature, expected):
        raise HTTPException(status_code=401, detail="Invalid signature")

    # Idempotency: dedupe on payload["event_id"] (reused on retries)

    if payload["status"] == "Approved":
        # Update user in database
        pass

    return {"received": True}
```

***

## Status sesi

Ini adalah 10 nilai yang mungkin untuk `status`, berupa string yang tepat dan peka huruf besar-kecil (perhatikan bahwa `Kyc Expired` menggunakan huruf `K` kapital tunggal):

| Status | Deskripsi |
| - | - |
| `Not Started` | Sesi dibuat tetapi pengguna belum membuka tautan. |
| `In Progress` | Pengguna sedang menyelesaikan verifikasi. |
| `In Review` | Verifikasi ditandai untuk peninjauan manual. |
| `Approved` | Semua pemeriksaan lolos. |
| `Declined` | Satu atau lebih pemeriksaan gagal. |
| `Resubmitted` | Peninjau meminta langkah tertentu untuk diulang. |
| `Awaiting User` | Sesi induk KYB menunggu pihak KYC anak menyelesaikan prosesnya. |
| `Abandoned` | Pengguna memulai tetapi tidak menyelesaikan dalam batas waktu yang tersedia. |
| `Expired` | Sesi kedaluwarsa sebelum pengguna membuka tautan. |
| `Kyc Expired` | Sesi yang sebelumnya disetujui, dengan dokumen yang telah melewati tanggal kedaluwarsanya. |

Lihat [Status verifikasi](https://docs.didit.me/id/integration/verification-statuses.md) untuk siklus hidup lengkap, transisi, dan diagram Mermaid.

***

## Langkah selanjutnya

1. **Pilih metode integrasi Anda**:
   * Aplikasi mobile → [SDK Native](https://docs.didit.me/id/integration/native-sdks/overview.md)
   * Aplikasi web → [SDK Web](https://docs.didit.me/id/integration/web-sdks/overview.md)
2. **Konfigurasikan webhook**: [Webhook](https://docs.didit.me/id/integration/webhooks.md)
3. **Rencanakan kapasitas**: [Batas laju](https://docs.didit.me/id/integration/rate-limiting.md)
4. **Tangani setiap status**: [Status verifikasi](https://docs.didit.me/id/integration/verification-statuses.md)
5. **Sesuaikan alur kerja Anda**: [Alur kerja](https://docs.didit.me/id/console/workflows.md)
6. **Pastikan API dapat dijangkau**: [Healthcheck](https://docs.didit.me/id/api-reference/healthcheck.md)

## Butuh bantuan?

* **Dukungan**: [support@didit.me](mailto:support@didit.me)
* **Onboarding terprogram**: [Pendaftaran terprogram](https://docs.didit.me/id/integration/programmatic-registration.md)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.