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

# Registrasi Programatik lewat Auth API

> Buat organisasi Didit secara programatik via Auth API tanpa browser. Bangun infrastruktur KYC sub-akun dengan bayar per panggilan, tanpa kontrak.



Prompt Registrasi Programatik
        Salin prompt ke papan klip



      
      

\<pre>

\``Programmatically create a pending Didit account — step 1 of the two-step onboarding (no browser, no console).

Endpoint:
POST https://apx.didit.me/auth/v2/programmatic/register/

Authentication:
None. This is a public endpoint. (Don't confuse the Auth API host `apx.didit.me/auth/v2` with the verification host `verification.didit.me/v3`.)

Request body:
\- email (string, required) — Any real, deliverable email (personal, work, alias). The verification code is mailed synchronously, so reserved test domains (`@example.com`, `@example.org`, `@*.test`, `@*.example`, `@*.invalid`) get rejected by mail delivery and the call returns `500` — substitute the placeholder with an inbox you can read.
\- password (string, required) — Must satisfy ALL of: minimum 8 characters, ≥1 uppercase letter (A-Z), ≥1 lowercase letter (a-z), ≥1 digit (0-9), ≥1 special character from !@#$%^&*()_+-=[]{}|;:,.<>?. Rules are validated one at a time and the first failure short-circuits.

curl example (replace `you@yourdomain.com` with a real inbox):
curl -X POST https://apx.didit.me/auth/v2/programmatic/register/ \
-H "Content-Type: application/json" \
-d '{
"email": "you@yourdomain.com",
"password": "MyStr0ng!Pass"
}'

Response (201 Created):
\- message (string) — "Registration successful. Check your email for the verification code."
\- email (string) — echoed back.

What happens server-side:
\- A pending account is created (NOT usable yet).
\- A 6-character alphanumeric code (e.g. "A3K9F2") is emailed to the supplied address.
\- The code is valid for 15 minutes. After expiry the registration must be redone.

Failure modes (all 400 unless noted):
\- Field-level: { "email": ["Enter a valid email address."] } or { "password": ["Ensure this field has at least 8 characters."] }.
\- Password-strength failures CURRENTLY return as a BARE ARRAY (no field key), one rule at a time: ["Password must contain at least one uppercase letter."] / lowercase / digit / special character. Known server-side inconsistency — treat as { "password": [...] } client-side.
\- Duplicate email: { "detail": "An account with this email already exists." }
\- 429 — { "detail": "Too many registration attempts. Please try again later.", "wait": <seconds> } when more than 5 registrations from the same IP within an hour.
\- 500 — returned (with an HTML body, not JSON) when mail delivery to the supplied address fails synchronously. Most commonly triggered by reserved test domains; use a real inbox.

Rate limits:
5 registrations per IP per hour.

Next step:
After receiving the email, call POST https://apx.didit.me/auth/v2/programmatic/verify-email/ with { "email", "code" } to get your access_token and api_key — see /auth-api/verify-email.

For end-to-end Didit integration, paste in the full prompt at /integration/integration-prompt.``

\</pre>



      
      

Tempel ke



## OpenAPI

````yaml id/openapi-auth.json POST /programmatic/register/
openapi: 3.0.0
info:
  version: 1.0.0
  title: Didit Auth API
  description: >-
    API pendaftaran dan autentikasi terprogram untuk pengembang dan agen AI.
    Daftar dalam 2 panggilan API -- tanpa perlu browser. Platform verifikasi
    identitas yang paling ramah agen.


    ## URL Dasar


    Semua endpoint dalam spesifikasi ini di-hosting di
    `https://apx.didit.me/auth/v2`. Ini adalah host yang berbeda dari API
    verifikasi (`https://verification.didit.me/v3`). Perhatikan perbedaannya:
    host autentikasi ini menerbitkan **token akses JWT** Anda dan memungkinkan
    Anda mencantumkan serta mengelola **organisasi** dan **aplikasi** Anda. Host
    verifikasi adalah tempat Anda memanggil sesi, alur kerja, AML, dll., yang
    diautentikasi dengan **`api_key`** yang dikembalikan oleh API ini.


    ## Cara kerja alur autentikasi


    1. `POST /programmatic/register/` — kirimkan email + kata sandi.

    2. Terima kode alfanumerik 6 karakter melalui email.

    3. `POST /programmatic/verify-email/` — kirimkan kode tersebut. Anda akan
    mendapatkan kembali JWT `access_token`, `refresh_token`, sebuah organisasi,
    dan aplikasi default dengan `client_id` + `api_key`.

    4. Simpan `api_key`. Gunakan sebagai `x-api-key` untuk setiap panggilan ke
    `https://verification.didit.me/v3/...`.

    5. Dari mesin mana pun di masa mendatang, `POST /programmatic/login/`
    menukarkan email + kata sandi Anda dengan JWT baru, lalu panggil `GET
    /organizations/me/` dan endpoint aplikasi untuk memulihkan atau merotasi
    kredensial.


    JWT hanya diperlukan untuk endpoint **Manajemen Akun** dalam spesifikasi
    ini; lalu lintas API verifikasi menggunakan `api_key` yang berjangka
    panjang, bukan JWT.


    ## Konvensi


    - Semua body permintaan dan respons berupa JSON (`Content-Type:
    application/json`).

    - **Gunakan alamat email asli yang dapat menerima pesan saat menguji `POST
    /programmatic/register/`.** Endpoint ini mengirimkan kode verifikasi secara
    sinkron, sehingga alamat pada domain pengujian yang dicadangkan
    (`@example.com`, `@example.org`, `@*.test`, `@*.example`, `@*.invalid`)
    ditolak oleh pengiriman email dan permintaan mengembalikan `500`. Ganti
    placeholder `you@yourdomain.com` dalam contoh dengan kotak masuk yang
    benar-benar dapat Anda baca.

    - Error validasi mengembalikan HTTP `400` dengan salah satu dari dua format:
    `{"field": ["message", ...]}` untuk masalah tingkat kolom, atau `{"detail":
    "message"}` untuk error aturan bisnis. Sejumlah kecil validator (kekuatan
    kata sandi saat mendaftar, kedaluwarsa kode saat verifikasi email) saat ini
    merespons dengan array sederhana `["message"]` alih-alih bentuk dengan kunci
    kolom -- ini adalah inkonsistensi sisi server yang diketahui, sehingga kode
    klien harus menerima kedua bentuk tersebut.

    - Error autentikasi kembali sebagai `{"detail": "..."}` dengan HTTP `401`
    (bearer token tidak valid) atau `403` (bearer token tidak ada / hak istimewa
    tidak memadai).

    - Respons batas laju menyertakan kolom `wait` dengan durasi cooldown dalam
    detik.
servers:
  - url: https://apx.didit.me/auth/v2
    description: Server autentikasi produksi
security: []
tags:
  - name: Programmatic Auth
    description: >-
      Siklus hidup akun dengan email dan kata sandi: daftar, verifikasi, masuk.
      Mengembalikan `access_token` JWT yang Anda gunakan untuk endpoint
      Manajemen Akun, ditambah (saat verifikasi) `client_id` dan `api_key`
      aplikasi pertama Anda.
  - name: Account Management
    description: >-
      Endpoint terautentikasi (JWT bearer) yang mencantumkan organisasi dan
      membuat, mengambil, atau memperbarui aplikasi. Gunakan endpoint ini untuk
      memulihkan atau merotasi `api_key` yang Anda gunakan untuk mengautentikasi
      panggilan API verifikasi.
paths:
  /programmatic/register/:
    post:
      tags:
        - Programmatic Auth
      summary: Daftarkan Akun
      description: >-
        Langkah 1 onboarding terprogram. Membuat akun berstatus pending dan
        mengirimkan kode 6 karakter melalui email (TTL 10 menit). Alamat
        diperiksa sebelum akun dibuat: alamat yang tidak dapat menerima kode
        akan mengembalikan 400 `email_undeliverable`. Batas laju: 5/IP/jam,
        ditambah kuota per jam bersama per jaringan (/24 untuk IPv4, /64 untuk
        IPv6).
      operationId: programmatic_register
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RegisterRequest'
            examples:
              Gmail:
                summary: Daftar dengan Gmail pribadi
                value:
                  email: you@yourdomain.com
                  password: MyStr0ng!Pass
              Work:
                summary: Daftar dengan email kantor
                value:
                  email: you@yourcompany.com
                  password: C0mplex#Pass1
      responses:
        '201':
          description: >-
            Pendaftaran berhasil. Kode verifikasi alfanumerik 6 karakter
            (misalnya `A3K9F2`) telah dikirimkan melalui email ke alamat yang
            diberikan dan berlaku selama 10 menit. Selanjutnya panggil `POST
            /programmatic/verify-email/`.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RegisterResponse'
              examples:
                Success:
                  value:
                    message: >-
                      Registration successful. Check your email for the
                      verification code.
                    email: you@yourdomain.com
        '400':
          description: >-
            Kesalahan validasi. Envelope yang dituju adalah `{"field": ["..."]}`
            untuk kesalahan tingkat kolom dan `{"detail": "..."}` untuk
            kesalahan aturan bisnis (misalnya email duplikat). Aturan kekuatan
            kata sandi saat ini merespons dengan array biasa `["..."]`, satu
            aturan pada satu waktu -- inkonsistensi sisi server yang sudah
            diketahui; perlakukan sebagai `{"password": ["..."]}` hingga
            diperbaiki. Ketika alamat tidak dapat menerima kode (domain sekali
            pakai, yang dicadangkan, atau uji coba, tidak ada server email,
            kemungkinan kesalahan ketik, atau alamat yang sebelumnya terpental),
            isi respons adalah `EmailUndeliverableError` dengan `code:
            "email_undeliverable"`; tidak ada akun yang dibuat atau diubah.
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/ValidationError'
                  - $ref: '#/components/schemas/EmailUndeliverableError'
              examples:
                MissingFields:
                  summary: Isi kosong
                  value:
                    email:
                      - This field is required.
                    password:
                      - This field is required.
                InvalidEmail:
                  summary: Email salah format
                  value:
                    email:
                      - Enter a valid email address.
                PasswordTooShort:
                  summary: Kata sandi kurang dari 8 karakter
                  value:
                    password:
                      - Ensure this field has at least 8 characters.
                PasswordMissingUppercase:
                  summary: Kata sandi tidak memiliki huruf besar
                  value:
                    - Password must contain at least one uppercase letter.
                PasswordMissingLowercase:
                  summary: Kata sandi tidak memiliki huruf kecil
                  value:
                    - Password must contain at least one lowercase letter.
                PasswordMissingDigit:
                  summary: Kata sandi tidak memiliki angka
                  value:
                    - Password must contain at least one digit.
                PasswordMissingSpecial:
                  summary: Kata sandi tidak memiliki karakter khusus
                  value:
                    - >-
                      Password must contain at least one special character
                      (!@#$%^&*()_+-=[]{}|;:,.<>?).
                Duplicate:
                  summary: Email sudah memiliki akun
                  value:
                    detail: An account with this email already exists.
                EmailUndeliverable:
                  summary: Alamat tidak dapat menerima email (domain sekali pakai)
                  value:
                    detail: >-
                      This email can't receive messages. Please use a different
                      email address.
                    code: email_undeliverable
                    reason: disposable_domain
                EmailLikelyTypo:
                  summary: Kemungkinan salah ketik pada domain
                  value:
                    detail: >-
                      This email can't receive messages. Please use a different
                      email address.
                    code: email_undeliverable
                    reason: possible_typo
                    suggestion: gmail.com
        '429':
          description: >-
            Dikenakan batas laju. Lebih dari 5 upaya pendaftaran dari IP yang
            sama dalam satu jam terakhir, atau anggaran per jam untuk jaringan
            pemanggil (/24 untuk IPv4, /64 untuk IPv6, yang dibagi bersama oleh
            pendaftaran dan pengiriman ulang kode) telah habis. Keduanya
            menyertakan `Retry-After: 3600`. Respons ini juga dikembalikan
            dengan header `Retry-After: 5` saat layanan sedang memeriksa kata
            sandi atau kode sebanyak mungkin secara bersamaan; coba lagi setelah
            jumlah detik yang ditunjukkan.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RateLimitError'
              examples:
                RateLimited:
                  value:
                    detail: Too many registration attempts. Please try again later.
                PasswordChecksBusy:
                  summary: >-
                    Terlalu banyak pemeriksaan kata sandi yang sedang
                    berlangsung
                  value:
                    detail: >-
                      Too many sign-in attempts are being processed right now.
                      Please try again in a few seconds.
      security:
        - {}
      x-codeSamples:
        - lang: curl
          label: cURL
          source: |-
            curl -X POST https://apx.didit.me/auth/v2/programmatic/register/ \
              -H "Content-Type: application/json" \
              -d '{
                "email": "you@yourdomain.com",
                "password": "MyStr0ng!Pass"
              }'
        - lang: python
          label: Python
          source: |-
            from didit import Didit

            # This call needs no API key.
            client = Didit()

            result = client.account.register(
                email="you@yourdomain.com",
                password="MyStr0ng!Pass",
            )
            print(result)
        - lang: javascript
          label: Node.js
          source: |-
            import Didit from "@didit-protocol/sdk-node";

            // This call needs no API key.
            const didit = new Didit();

            const result = await didit.account.register({
              email: "you@yourdomain.com",
              password: "MyStr0ng!Pass",
            });
            console.log(result);
        - lang: go
          label: Go
          source: "ctx := context.Background()\n// This call needs no API key.\nclient := didit.NewClient()\n\nresult, err := client.Account.Register(ctx, didit.RegisterRequest{\n\tEmail:    \"you@yourdomain.com\",\n\tPassword: \"MyStr0ng!Pass\",\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
        - lang: java
          label: Java
          source: |-
            import me.didit.Didit;
            import me.didit.types.RegisterRequest;

            // This call needs no API key.
            Didit client = new Didit();

            var result = client.account().register(RegisterRequest.builder()
                    .email("you@yourdomain.com")
                    .password("MyStr0ng!Pass")
                    .build());
            System.out.println(result);
        - lang: php
          label: PHP
          source: |-
            <?php

            require 'vendor/autoload.php';

            use Didit\DiditClient;

            // This call needs no API key.
            $didit = new DiditClient();

            $result = $didit->account->register([
                'email' => 'you@yourdomain.com',
                'password' => 'MyStr0ng!Pass',
            ]);
            print_r($result->toArray());
        - lang: ruby
          label: Ruby
          source: |-
            require "didit"

            # This call needs no API key.
            didit = Didit::Client.new

            result = didit.account.register(
              email: "you@yourdomain.com",
              password: "MyStr0ng!Pass"
            )
            puts result.to_h
        - lang: csharp
          label: .NET
          source: |-
            using System;
            using System.Text.Json;
            using Didit;

            // This call needs no API key.
            using var client = new DiditClient();

            var result = await client.Account.RegisterAsync(new RegisterRequest
            {
                Email = "you@yourdomain.com",
                Password = "MyStr0ng!Pass",
            });
            Console.WriteLine(JsonSerializer.Serialize(result));
components:
  schemas:
    RegisterRequest:
      type: object
      required:
        - email
        - password
      properties:
        email:
          type: string
          format: email
          description: >-
            Alamat email valid apa pun (pribadi, kantor, alias). Digunakan
            sebagai pengidentifikasi akun unik.
          example: you@yourdomain.com
        password:
          type: string
          minLength: 8
          description: >-
            Minimal 8 karakter. Harus berisi setidaknya satu huruf besar
            (`A-Z`), satu huruf kecil (`a-z`), satu angka (`0-9`), dan satu
            karakter khusus dari `!@#$%^&*()_+-=[]{}|;:,.<>?`. Validasi
            melaporkan satu aturan yang gagal pada satu waktu.
          example: MyStr0ng!Pass
    RegisterResponse:
      type: object
      properties:
        message:
          type: string
          description: >-
            Konfirmasi yang mudah dibaca manusia bahwa kode verifikasi telah
            dikirim.
          example: Registration successful. Check your email for the verification code.
        email:
          type: string
          format: email
          description: Email tujuan pengiriman kode verifikasi.
          example: you@yourdomain.com
    ValidationError:
      description: >-
        Isi kesalahan validasi. Envelope yang diharapkan adalah pemetaan
        `{field: ["message", ...]}` untuk kesalahan tingkat kolom atau envelope
        kunci tunggal `{detail: "..."}` untuk kesalahan aturan bisnis. Sejumlah
        kecil validator (kekuatan kata sandi saat mendaftar, validitas kode pada
        verifikasi email) saat ini merespons dengan array polos `["message"]` --
        inkonsistensi sisi server yang sudah diketahui. Skema di bawah ini
        mempertahankan cabang array polos tersebut sehingga kode klien yang
        dihasilkan dari spesifikasi ini mendeserialisasi respons saat ini, namun
        kode klien baru harus memperlakukannya sebagai bentuk dengan kunci kolom
        yang relevan (`{password: [...]}` atau `{code: [...]}`) dan kontrak
        server akan disesuaikan ke bentuk tersebut.
      oneOf:
        - type: object
          additionalProperties:
            type: array
            items:
              type: string
          example:
            email:
              - Enter a valid email address.
        - type: object
          properties:
            detail:
              type: string
          example:
            detail: An account with this email already exists.
        - type: array
          items:
            type: string
          example:
            - Invalid or expired verification code.
    EmailUndeliverableError:
      type: object
      description: >-
        Dikembalikan oleh `POST /programmatic/register/` ketika alamat tidak
        dapat menerima kode verifikasi. Pemeriksaan berjalan sebelum akun dibuat
        atau diubah, sehingga tidak ada yang tersisa.
      required:
        - detail
        - code
        - reason
      properties:
        detail:
          type: string
          description: Pesan yang mudah dibaca manusia.
          example: >-
            This email can't receive messages. Please use a different email
            address.
        code:
          type: string
          enum:
            - email_undeliverable
          description: Selalu `email_undeliverable`.
        reason:
          type: string
          enum:
            - invalid_address
            - reserved_domain
            - no_mail_records
            - disposable_domain
            - possible_typo
            - suppressed
          description: >-
            Alasan mengapa alamat ditolak: `invalid_address` (bukan alamat yang
            valid), `reserved_domain` (domain yang dicadangkan atau domain
            pengujian seperti `example.com`), `no_mail_records` (domain tidak
            memiliki server email), `disposable_domain` (penyedia kotak surat
            sekali pakai), `possible_typo` (kemungkinan salah ketik pada
            penyedia umum; lihat `suggestion`), `suppressed` (alamat sebelumnya
            memantul atau mengajukan keluhan).
        suggestion:
          type: string
          description: >-
            Domain yang kemungkinan dimaksudkan, hanya ada jika domain terlihat
            seperti salah ketik (misalnya `gmail.com` untuk `gmial.com`). API
            tidak menerima konfirmasi: daftarkan kembali dengan alamat yang
            telah diperbaiki.
          example: gmail.com
    RateLimitError:
      type: object
      description: >-
        Respons batas laju atau penguncian progresif. `wait` adalah waktu tunggu
        dalam hitungan detik.
      properties:
        detail:
          type: string
          example: >-
            Too many login attempts from this IP address. Please wait before
            trying again.

````

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