> ## 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.

# Pendaftaran Programatik: API KYC untuk Agen AI

> Daftar dan dapatkan kredensial API Didit dalam 2 panggilan API tanpa browser. Platform verifikasi identitas paling ramah agen AI untuk Cursor, Claude, Devin.

## Ringkasan

Didit adalah **platform verifikasi identitas yang paling ramah untuk agen**. Agen pengodean AI (Cursor, Claude Code, GitHub Copilot, Devin, OpenHands, Codex) dapat mendaftar, mengonfigurasi alur kerja, dan memulai verifikasi identitas, semuanya secara programatik tanpa pernah membuka browser.

**Mengapa agen menyukai Didit:**

* **2 panggilan API** dari nol hingga mendapatkan kredensial (register + verify-email).
* **Tanpa browser**: sepenuhnya headless, cocok untuk CI/CD dan alur kerja agen.
* **Tanpa faktor kedua pada akun API baru:** token dikembalikan segera setelah verifikasi email.
* **Organisasi dan aplikasi disiapkan otomatis** dengan `api_key` dalam respons verifikasi.
* **API manajemen lengkap**: konfigurasikan alur kerja, kuesioner, daftar, dan penagihan, semuanya melalui API.
* **Server MCP tersedia**: agen dapat menemukan dan menggunakan alat Didit secara bawaan.

Kontrak lengkapnya dipublikasikan sebagai [openapi-auth.json](https://docs.didit.me/openapi-auth.json), dan endpoint di bawah ini telah diaudit terhadap kontrak tersebut.

## URL dasar

Semua endpoint dalam panduan ini berada di **host auth**:

```
https://apx.didit.me/auth/v2
```

Host ini berbeda dari API verifikasi (`https://verification.didit.me/v3`). Host auth menerbitkan token akses JWT dan mengelola aplikasi. Host verifikasi menjalankan sesi, AML, alur kerja, dan lainnya, yang diautentikasi dengan `api_key` berumur panjang yang Anda dapatkan dari alur ini.

## Mulai cepat

> [!WARNING]
>
> **Gunakan alamat email nyata yang dapat menerima pesan.** Endpoint mengirim kode verifikasi secara sinkron, sehingga domain uji yang dicadangkan (`@example.com`, `@example.org`, `@*.test`, `@*.example`, `@*.invalid`) ditolak oleh pengiriman email dan panggilan akan mengembalikan `500`. Ganti placeholder `you@yourdomain.com` di bawah dengan kotak masuk yang bisa Anda baca.

### Langkah 1: Daftar

```bash theme={null}
curl -X POST https://apx.didit.me/auth/v2/programmatic/register/ \
  -H "Content-Type: application/json" \
  -d '{"email": "you@yourdomain.com", "password": "MyStr0ng!Pass"}'
```

**Respons** (`201 Created`):

```json theme={null}
{
  "message": "Registration successful. Check your email for the verification code.",
  "email": "you@yourdomain.com"
}
```

Kode verifikasi alfanumerik 6 karakter (misalnya `A3K9F2`) dikirim melalui email ke alamat tersebut. **Kode kedaluwarsa 10 menit setelah dikirim**. Jika sudah kedaluwarsa, panggil endpoint ini lagi dengan email dan kata sandi yang sama: untuk akun yang belum terverifikasi, endpoint mengembalikan `200` dengan `"A new verification code has been sent to your email."` dan kode baru. Endpoint khusus `POST /programmatic/resend-otp/` (body: `{"email", "password"}`) juga mengirim ulang kode, dengan jeda 60 detik antarpengiriman. Kedua rute ini berbagi batas laju pendaftaran di bawah.

### Langkah 2: Verifikasi kode dan dapatkan kredensial

```bash theme={null}
curl -X POST https://apx.didit.me/auth/v2/programmatic/verify-email/ \
  -H "Content-Type: application/json" \
  -d '{"email": "you@yourdomain.com", "code": "A3K9F2"}'
```

**Respons** (`200 OK`):

```json theme={null}
{
  "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
  "refresh_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
  "expires_in": 86400,
  "organization": {
    "uuid": "a1b2c3d4-5678-90ab-cdef-111111111111",
    "name": "developer"
  },
  "application": {
    "uuid": "b2c3d4e5-6789-01bc-defg-222222222222",
    "name": "developer",
    "client_id": "S9LIYGSoWNuGMLHsvEt9dQ",
    "api_key": "sk_live_example_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
  }
}
```

Sekarang Anda sudah memiliki semua yang dibutuhkan. Simpan `application.api_key` dengan aman dan kirimkan sebagai header `x-api-key` pada setiap panggilan API verifikasi.

> [!NOTE]
>
> Token adalah **JWT yang ditandatangani RS256**. `expires_in` secara default adalah **86400 detik (24 jam)**. Token akses hanya diperlukan untuk endpoint manajemen di `apx.didit.me/auth/v2`. Lalu lintas API verifikasi di `verification.didit.me/v3` diautentikasi dengan `api_key` berumur panjang, bukan JWT.

### Langkah 3: Gunakan API

```bash theme={null}
curl https://verification.didit.me/v3/sessions/ \
  -H "x-api-key: sk_live_example_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
```

## Login berikutnya

Dari mesin mana pun di kemudian hari, tukarkan email dan kata sandi Anda dengan JWT baru:

```bash theme={null}
curl -X POST https://apx.didit.me/auth/v2/programmatic/login/ \
  -H "Content-Type: application/json" \
  -d '{"email": "you@yourdomain.com", "password": "MyStr0ng!Pass"}'
```

Endpoint ini langsung mengembalikan `access_token` + `refresh_token`, tanpa browser. Setelah itu, panggil `GET /organizations/me/` untuk menemukan `org_id` Anda (`uuid` organisasi), lalu `GET /organizations/me/{org_id}/applications/` untuk mencantumkan aplikasi organisasi (`uuid` setiap entri adalah `app_id`), dan terakhir `GET /organizations/me/{org_id}/applications/{app_id}/` untuk mengambil `api_key`.

> [!NOTE]
>
> Akun email/kata sandi yang dibuat di konsol juga dapat menggunakan `POST /programmatic/login/` setelah email diverifikasi. Akun konsol yang hanya menggunakan OAuth harus menetapkan kata sandi terlebih dahulu sebelum menggunakan endpoint login headless ini.

### Saat login meminta lebih

`POST /programmatic/login/` hanya mengembalikan token jika akun tidak memiliki faktor kedua.
Ada tiga respons lain yang mungkin, dan agen yang menulis skrip login harus menanganinya:

| Akun | Respons |
| - | - |
| Memiliki aplikasi autentikator atau kunci sandi | `200` dengan `{"2fa_required": true, "temp_token": "...", "has_passkeys": true, "has_authenticator": false}` dan tanpa token |
| Organisasinya menerapkan SSO | `403` dengan `{"error": "sso_required", "message": "...", "organization_name": "...", "organization_slug": "...", "sso_url": "/sso/<slug>"}` |
| Telah dipulihkan dan belum memiliki metode login | `403` dengan `"code": "recovery_setup_required"`, dan tautan untuk menyiapkannya dikirim ke alamat akun |

Kunci API tidak memerlukan login, jadi gunakan kunci API untuk semua yang diotomatisasi: akun dengan faktor kedua tidak dapat menyelesaikan login melalui endpoint ini.

## Persyaratan kata sandi

Diterapkan di sisi server, **satu aturan pada satu waktu**. Kegagalan pertama langsung menghentikan pemeriksaan dan menghasilkan error berupa array polos, seperti `["Password must contain at least one uppercase letter."]`. (Error validasi lain pada endpoint ini menggunakan envelope `{"password": [...]}` yang diberi kunci per kolom. Bentuk array polos pada aturan kekuatan kata sandi adalah inkonsistensi sisi server yang sudah diketahui. Perlakukan sebagai `{"password": [...]}` dalam kode klien.)

| Aturan | Detail |
| - | - |
| Panjang minimum | 8 karakter |
| Huruf kapital | Minimal satu `A–Z` |
| Huruf kecil | Minimal satu `a–z` |
| Angka | Minimal satu `0–9` |
| Karakter khusus | Minimal satu dari `!@#$%^&*()_+-=[]{}\|;:,.<>?` |

## Batas laju dan penguncian

Tiga kontrol independen melindungi host autentikasi. Salah satunya dapat memicu respons `429`. Header respons `Retry-After` memberi tahu Anda berapa lama harus menunggu sebelum mencoba lagi.

| Cakupan | Batas |
| - | - |
| Registrasi | **5** percobaan per **IP** per **jam** (dibagi dengan `POST /programmatic/resend-otp/`). |
| Verifikasi email | **10** percobaan kode per **email** per **jam** dan **50** per **IP** sumber per **jam**, ditambah jeda eksponensial di antara percobaan (30 detik, digandakan setiap kegagalan, maksimum 1 jam). |
| Login (IP) | **20** percobaan per **IP** per **menit**, dan **100** per **IP** per **jam**. |
| Login (email) | Penguncian bertahap pada akun: **5** kegagalan berturut-turut → penguncian 15 menit; **10** → 1 jam; **20** → 24 jam. |

Badan respons `429` terlihat seperti ini:

```json theme={null}
{ "detail": "Too many login attempts from this IP address. Please wait before trying again." }
```

Batas laju API verifikasi (misalnya 600 sesi/menit) bersifat independen dan didokumentasikan di [Batas laju](https://docs.didit.me/id/integration/rate-limiting.md).

## Mengelola aplikasi

Setelah diautentikasi, Anda dapat mengambil, membuat, atau memperbarui aplikasi di dalam organisasi Anda.

Ini sangat cocok untuk **reseller** yang menginginkan satu aplikasi per pelanggan. Setiap aplikasi memiliki `client_id`, `api_key`, metadata, dan pengaturan sendiri. Fitur ini juga berguna jika organisasi Anda memiliki produk, merek, wilayah, lingkungan, atau kasus penggunaan berbeda yang ingin Anda pisahkan.

```bash theme={null}
# 1. Discover your org_id
curl https://apx.didit.me/auth/v2/organizations/me/ \
  -H "Authorization: Bearer $ACCESS_TOKEN"

# 2. List the organization's applications (each entry's uuid is an app_id)
curl "https://apx.didit.me/auth/v2/organizations/me/$ORG_ID/applications/" \
  -H "Authorization: Bearer $ACCESS_TOKEN"

# 3. Create an application for a customer, product, or environment
curl -X POST "https://apx.didit.me/auth/v2/organizations/me/$ORG_ID/applications/" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Acme Customer App",
    "website_url": "https://acme.example",
    "redirect_uris": ["https://acme.example/callback"],
    "terms_url": "https://acme.example/terms",
    "privacy_url": "https://acme.example/privacy"
  }'

# 4. Recover credentials (client_id + api_key) for an existing application
curl "https://apx.didit.me/auth/v2/organizations/me/$ORG_ID/applications/$APP_ID/" \
  -H "Authorization: Bearer $ACCESS_TOKEN"

# 5. Update application metadata (PATCH — uuid, client_id, api_key never change)
curl -X PATCH "https://apx.didit.me/auth/v2/organizations/me/$ORG_ID/applications/$APP_ID/" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Acme Production App",
    "website_url": "https://app.acme.example"
  }'
```

Untuk membuat daftar, membuat, atau memperbarui aplikasi, pengguna harus berstatus **owner** atau **admin** di organisasi target; jika tidak, respons akan berupa `403`.

## Apa yang dapat dilakukan agen setelah registrasi?

Dengan `api_key`, agen memiliki akses penuh ke API verifikasi. Jalur yang diaudit pada `https://verification.didit.me/v3`:

| API | Fungsi |
| - | - |
| `POST /v3/session/` | Membuat sesi verifikasi. |
| `GET /v3/sessions/` | Menampilkan daftar sesi. |
| `GET /v3/session/{id}/decision/` | Mengambil keputusan V3 (array jamak, lihat Model data). |
| `GET /v3/workflows/` | Menampilkan daftar alur kerja verifikasi. |
| `GET /v3/questionnaires/` | Menampilkan daftar kuesioner kustom. |
| `GET /v3/users/` | Menampilkan daftar pengguna akhir (diindeks menurut `vendor_data`). |
| `GET /v3/billing/balance/` | Memeriksa saldo kredit. |
| `POST /v3/billing/top-up/` | Mengisi saldo kredit. |
| `GET /v3/webhook/destinations/` | Mengelola tujuan webhook (daftar / buat / perbarui / hapus). |

Lihat [referensi Management API](https://docs.didit.me/id/sessions-api/management-api.md) untuk cakupan lengkapnya.

## Integrasi server MCP

Untuk pengalaman agen terbaik, gunakan server MCP Didit yang di-hosting di `https://mcp.didit.me/mcp`. Server ini tidak memerlukan kunci API: saat pertama kali terhubung, klien Anda akan membuka browser, Anda **masuk dengan Didit** (OAuth 2.1 dengan PKCE), dan server bertindak atas nama Anda dengan izin sesuai peran konsol Anda. Klien yang mendukung MCP jarak jauh secara native (Cursor, VS Code) menggunakan entri ini; Claude web dan Desktop menambahkannya sebagai konektor kustom:

```json theme={null}
{
  "mcpServers": {
    "didit": {
      "url": "https://mcp.didit.me/mcp"
    }
  }
}
```

Claude Code: `claude mcp add --transport http didit https://mcp.didit.me/mcp`. Klien yang hanya mendukung stdio (Windsurf, Zed) menggunakan jembatan `mcp-remote`, yang menjalankan alur OAuth untuk Anda.

Kunci API yang Anda terima dari alur registrasi di atas ditujukan untuk memanggil REST API dari backend Anda sendiri; MCP tidak pernah menggunakannya. Lihat [ikhtisar MCP](https://docs.didit.me/id/integration/mcp/overview.md) dan [instalasi per klien](https://docs.didit.me/id/integration/mcp/installation.md) untuk detailnya.

## Referensi format kesalahan

Semua endpoint `apx.didit.me/auth/v2` menggunakan tiga bentuk respons yang sama (lihat `openapi-auth.json`):

* **Validasi tingkat kolom**: `{"field": ["message", ...]}` dengan HTTP `400`.
* **Validasi tingkat formulir** (terutama kekuatan kata sandi dan kesalahan kode verifikasi): array polos `["Invalid or expired verification code."]` dengan HTTP `400`.
* **Autentikasi / aturan bisnis**: `{"detail": "..."}` dengan `400`, `401`, `403`, `404`, atau `429`. Respons `429` menyertakan header respons `Retry-After` yang memberi tahu Anda berapa lama harus menunggu (badannya hanya berisi `detail`).

Host verifikasi mengembalikan kesalahan sebagai `{"detail": "..."}`, dan respons 429 menyertakan `X-RateLimit-*` dan `Retry-After`. Lihat [Batas laju](https://docs.didit.me/id/integration/rate-limiting.md).


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